gettext-mcp 0.1.0

Model Context Protocol (MCP) server for managing GNU gettext .po/.pot translation files, with CRUD tools and an optional web UI.
Documentation

Gettext MCP Server

A Model Context Protocol (MCP) server for managing GNU gettext .po/.pot files. Provides tools for reading, editing, and managing translations with support for contexts, plural forms, flags, and metadata.

Features

  • MCP Tools: Full set of tools for translation CRUD operations
  • Web UI: Optional human-friendly web interface for browsing and editing translations
  • Plural Form Support: Handle msgid_plural and plural translations
  • Context Support: Disambiguate identical strings with msgctxt
  • Metadata Management: Manage PO file headers and language settings
  • Concurrent Access: Thread-safe operations with Arc
  • File Discovery: Auto-discover .po/.pot files or use explicit paths
  • Format Preservation: Parse and serialize PO format with structure preservation

Installation

Prerequisites

  • Rust 1.70+ (with Cargo)
  • For web UI: environment variables WEB_PORT and optionally WEB_HOST

Install

cargo install --path .
# This will install `gettext-mcp` into `~/.cargo/bin/`

Configuration

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "gettext": {
      "command": "gettext-mcp",
      "args": ["/path/to/your/priv/gettext"]
    }
  }
}

Usage

Single File Mode

Start the server with a default PO file:

./gettext-mcp /path/to/translations.po

Tools can omit the path parameter to use the default file.

Directory Mode

Point the server at a gettext directory to auto-discover all .po/.pot files recursively:

./gettext-mcp /path/to/priv/gettext

This scans the directory tree (e.g., {lang}/LC_MESSAGES/*.po, *.pot) and pre-loads all files at startup. Tools accept relative paths within the directory:

{ "path": "sv/LC_MESSAGES/default.po" }

Use the list_files tool to see all discovered files.

Dynamic Path Mode

Without specifying a path, the server will accept dynamic paths from MCP tool calls:

./gettext-mcp

All tools will require explicit path parameters.

With Web UI

Enable the optional web interface:

WEB_PORT=8787 WEB_HOST=127.0.0.1 ./gettext-mcp /path/to/priv/gettext

Then access the UI at http://127.0.0.1:8787

MCP Tools

Translation CRUD

list_translations

List translations with optional filtering and pagination.

Parameters:

  • path: (optional) Path to .po file (required if not using default)
  • query: (optional) Search query (searches msgid and msgstr)
  • limit: (optional) Maximum number of results

Returns: Array of translation records

get_translation

Fetch a single translation entry.

Parameters:

  • path: (optional) Path to .po file
  • msgid: The message ID to fetch
  • msgctxt: (optional) Message context for disambiguation

Returns: Translation details (msgid, msgstr, msgctxt, plural forms, flags, comments, source locations)

upsert_translation

Create or update a translation entry.

Parameters:

  • path: (optional) Path to .po file
  • msgid: The message ID
  • msgstr: (optional) The translated string
  • msgctxt: (optional) Message context
  • msgid_plural: (optional) Plural form of the message ID
  • msgstr_plural: (optional) Array of plural translations [index 0 = singular, 1 = plural, ...]
  • flags: (optional) Array of flags (fuzzy, c-format, etc)

Returns: Success response

delete_translation

Remove a specific translation.

Parameters:

  • path: (optional) Path to .po file
  • msgid: The message ID
  • msgctxt: (optional) Message context

Returns: Success response

delete_key

Remove all contexts of a message.

Parameters:

  • path: (optional) Path to .po file
  • msgid: The message ID

Returns: Success response

Metadata Tools

set_comment

Set or clear translator comments on a translation.

Parameters:

  • path: (optional) Path to .po file
  • msgid: The message ID
  • msgctxt: (optional) Message context for disambiguation
  • comment: (optional) Comment text (omit to clear)

set_fuzzy

Toggle or set the fuzzy flag.

Parameters:

  • path: (optional) Path to .po file
  • msgid: The message ID
  • msgctxt: (optional) Message context for disambiguation
  • fuzzy: Boolean flag state

set_flag

Manage specific flags (c-format, python-format, etc).

Parameters:

  • path: (optional) Path to .po file
  • msgid: The message ID
  • msgctxt: (optional) Message context for disambiguation
  • flag: Flag name
  • enabled: Boolean to enable/disable flag

File/Language Tools

list_files

List all discovered .po/.pot files (useful in directory mode).

Parameters: None

Returns: Array of file objects with path and relative_path, plus count and base_dir

list_metadata

Get file metadata (encoding, language, plural forms).

Parameters:

  • path: (optional) Path to .po file

Returns: Metadata object with encoding, language, plural_forms

set_header

Update a metadata header value.

Parameters:

  • path: (optional) Path to .po file
  • key: Header key (e.g., "Language", "Content-Type")
  • value: (optional) Header value. Omit to remove the header key.

list_contexts

Get all msgctxt values in the file.

Parameters:

  • path: (optional) Path to .po file

Returns: Array of context strings

list_languages (Web UI only)

List languages in the file.

add_language (Web UI only)

Add a language to the file.

remove_language (Web UI only)

Remove a language from the file.

Web UI Features

Translation Browser

  • Real-time search and filtering
  • Display translation status (translated, fuzzy, untranslated)
  • Support for plural forms
  • Comment and metadata display

Translation Editor

  • Edit msgid and msgstr inline
  • Manage fuzzy flag status
  • Add/update comments
  • Handle plural forms

File Management

  • Select and switch between multiple .po files
  • View per-file statistics
  • Progress indicator showing translation coverage

Language Management

  • View available languages
  • Add new languages
  • Remove languages

PO File Format

This server supports the standard GNU gettext .po format:

# Translator comment
#. Extracted comment
#: source/file.py:42
#, fuzzy, c-format
msgctxt "context"
msgid "Original text"
msgid_plural "Original texts"
msgstr "Translated text"
msgstr[0] "Singular translation"
msgstr[1] "Plural translation"

Examples

Example .po Files

Sample files are included in examples/:

  • sample_en.pot - English template file
  • sample_fr.po - French translation example
  • sample_plurals.po - Example with plural forms and contexts

API Usage Examples

Using with Claude

When using the MCP server with Claude, you can ask:

"Translate 'Hello' to French in the translations.po file"
"Show me all untranslated strings"
"Mark the entry 'Save' as fuzzy"
"Add German language to the project"

Direct MCP Tool Calls

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "list_translations",
    "arguments": {
      "path": "/path/to/file.po",
      "query": "hello",
      "limit": 10
    }
  }
}

Architecture

The server follows a clean three-layer architecture:

  1. Store Layer (src/store.rs)

    • Handles PO file parsing and serialization
    • In-memory representation with Arc for thread safety
    • CRUD operations and metadata management
  2. MCP Server Layer (src/mcp_server.rs)

    • Tool definitions and parameter handling
    • Error mapping to MCP error types
    • JSON response formatting
  3. Web UI Layer (src/web/mod.rs)

    • Axum HTTP server
    • Embedded SPA with React-like frontend
    • REST API endpoints mirroring MCP tools

Testing

Run the test suite:

cargo test

Tests cover:

  • PO format parsing and serialization
  • Store CRUD operations
  • Concurrent access patterns
  • Plural form handling
  • Context disambiguation
  • Metadata operations
  • Web UI functionality

Performance Considerations

  • Memory: Entire PO file loaded in memory (suitable for catalogs <1MB)
  • Disk I/O: Changes written to disk after each modification
  • Search: Linear scan of all translations (fine for <10k entries)
  • Concurrency: Multiple readers OR one writer (designed for interactive use)

Configuration

Environment Variables

  • WEB_PORT: Enable web UI on specified port (e.g., 8787)
  • WEB_HOST: Bind web server to address (default: 127.0.0.1)
  • RUST_LOG: Set logging level (e.g., info, debug)

Command Line

  • First argument: Path to a .po file or a gettext directory (optional). When a directory is given, all .po/.pot files are discovered recursively at startup.

Troubleshooting

Web UI won't start

Ensure WEB_PORT environment variable is set:

    WEB_PORT=8787 ./gettext-mcp

File not found

Use absolute paths when specifying .po files:

./gettext-mcp /absolute/path/to/file.po

Connection issues with Claude

Ensure the MCP server is properly registered in Claude's configuration and has read/write permissions to the PO files.

Contributing

Contributions welcome! Areas for enhancement:

  • Performance optimization for large catalogs
  • Additional format support (.json, .yaml, etc)
  • Fuzzy matching and suggestion features
  • Git integration for version control
  • CI/CD pipeline improvements

License

MIT License

Related Projects

Support

For issues or questions:

  1. Check the troubleshooting section above
  2. Review the test files for usage examples
  3. Consult the MCP specification for protocol details