localizely-mcp
by adborroto
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).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues