Skip to main content
Glama
README.md
# localizely-mcp

MCP server for [Localizely](https://localizely.com) — manage translation files (Flutter ARB, iOS .strings, Android XML, JSON, and more) from any MCP-compatible client (Claude Desktop, Claude Code, Cursor, etc.) via natural language.

## Tools

| Tool | Description |
|------|-------------|
| `localizely_get_status` | Per-language translation completion stats (total keys, translated, reviewed, progress %) |
| `localizely_download_file` | Download translation file(s) in a chosen format |
| `localizely_upload_file` | Upload a translation file to add/update strings |
| `localizely_update_key` | Update a single translation key without touching the rest of the file |
| `localizely_create_branch` | Create a new translation branch |
| `localizely_delete_branch` | Delete a translation branch |

Supported file formats: `flutter_arb`, `json`, `android_xml`, `ios_strings`, `ios_stringsdict`, `java_properties`, `rails_yaml`, `angular_xlf`, `dotnet_resx`, `po`, `pot`, `csv`, `xlsx`.

The Localizely API does not expose per-string CRUD — bulk operations go through file upload/download; `localizely_update_key` builds a tiny single-key file under the hood for one-off edits.

## Requirements

- Python 3.10+
- A Localizely account and project
- A Localizely **private API key** — Account settings → API keys → https://app.localizely.com/settings/api-keys
- [uv](https://docs.astral.sh/uv/) installed (`uvx` ships with it) — recommended, no local clone or venv needed

This package is **not published to PyPI**. It runs directly from this public GitHub repo via `uv`'s git support — no separate deploy or publish step required.

## Usage

### Claude Desktop / Claude Code — recommended (`uvx`, no clone needed)

Add to your MCP config (`claude_desktop_config.json` or `.mcp.json`):

```json
{
  "mcpServers": {
    "localizely": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/adborroto/localizely-mcp", "localizely-mcp"],
      "env": {
        "LOCALIZELY_API_TOKEN": "your-api-token",
        "LOCALIZELY_PROJECT_ID": "your-project-uuid"
      }
    }
  }
}
```

`uvx` fetches the repo, builds an isolated environment, and runs the `localizely-mcp` entry point on demand — nothing to install or update manually. Pin a specific commit/tag for stability with `git+https://github.com/adborroto/localizely-mcp@<tag-or-sha>`.

Restart the client after editing the config.

### Local clone (alternative)

```bash
git clone https://github.com/adborroto/localizely-mcp.git
cd localizely-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install .

cp .env.example .env
# edit .env and set LOCALIZELY_API_TOKEN
```

Then point your MCP config at the venv's Python directly:

```json
{
  "mcpServers": {
    "localizely": {
      "command": "/absolute/path/to/localizely-mcp/.venv/bin/localizely-mcp",
      "env": {
        "LOCALIZELY_API_TOKEN": "your-api-token",
        "LOCALIZELY_PROJECT_ID": "your-project-uuid"
      }
    }
  }
}
```

The server communicates over stdio, as expected by the MCP protocol — it's not meant to be run interactively.

## Finding your project ID

Every tool takes a `project_id`. Find it on the **My projects** page in the Localizely web app — it's the UUID in the project URL or project settings.

If you mostly work with a single project, set `LOCALIZELY_PROJECT_ID` in your environment (or MCP config `env` block) instead of passing `project_id` on every call — each tool falls back to it when the argument is omitted. You can still pass `project_id` explicitly to target a different project on a one-off call.

## Security

- Never commit your `.env` file or hardcode your API token — `.gitignore` already excludes `.env`.
- The API token is read from the environment at startup; the server refuses to start without it.
- Treat your Localizely API key like any other credential: scope it to what you need, rotate it if it leaks, and don't share it in issues, PRs, or logs.

If you find a security issue, please open a private report rather than a public issue.

## License

MIT — see [LICENSE](LICENSE).