Localizing a React app with the Tolgee MCP server
·
...

Dmitrii Bocharov
Senior Software Developer

In the era of vibe coding, the agent in your editor is doing more of the work, and the useful question is how much of your stack it can reach. We want ours to be as capable as possible, and for localization, that means giving it direct access to Tolgee. The MCP server is what gives the agent that power: it can create keys, machine-translate them, tag them, and read the state of a project without you touching the Tolgee UI or shuttling JSON files around.
An agent can already reach Tolgee's REST API with curl, so why an MCP server? Because a raw API is a blank wall - the agent has to know which endpoints exist, what they expect, and how they fit together, and it will guess wrong. The MCP server hands the agent a typed list of tools instead. It can see that it can create a key, tag it, list the project's languages, check translation state, and run a batch machine-translation job. That visibility is what lets it make good decisions and compose its own workflow: it checks which languages exist before translating, tags a new key to match its neighbors, verifies before deleting. The tool list is context, and context is what turns "call an API" into "get the job done."
This is a hands-on walkthrough. We'll connect Claude Code to Tolgee, point it at a real React example app, and drive two everyday workflows through the agent: adding strings for a new feature, and filling in missing translations in bulk.
What the MCP server actually is
A quick note on shape, because it's not what people expect from "an MCP server." There's nothing to npm install and no local process to run. The Tolgee MCP server is remote - it's an HTTP endpoint hosted alongside your Tolgee instance:
Tolgee Cloud:
https://app.tolgee.io/mcp/developerSelf-hosted:
https://<your-instance>/mcp/developer
It speaks the standard streamable-HTTP MCP protocol and authenticates with a header. The /developer in the path is a role: it grants the surface a developer needs - working with keys, translations, languages, tags, namespaces, branches, and batch operations. (Translator and project-manager roles are on the way.) The usage guide has the current, detailed tool list.
Connecting Claude Code
First you need a key. In Tolgee, open your project and generate a Project API Key (PAK) - or a Personal Access Token (PAT) if you want access across all your projects. The tradeoff:
A PAK is scoped to a single project. The agent never has to pass a
projectId, and a mistake can't reach into other projects. This is the safer default.A PAT inherits your full user permissions across every project you can see. Handy when you jump between projects, but there's more to lose.
For this walkthrough, use a PAK for the example project.
Now register the server with Claude Code - one command:
That's the whole setup. The X-API-Key header is how the server authenticates you; the --transport http flag tells Claude Code this is a remote server rather than a local command. For config in other clients, see the setup guide.
Verify the connection the way you'd verify any integration - ask for something read-only:
You: List all languages in the Tolgee project.
If the agent comes back with the project's languages, you're connected. Starting with a read-only call is a good habit in general: confirm connectivity before anything writes.
The example app
We'll use the official Tolgee React example - the react testapps from the tolgee-js monorepo. It's a small Vite + @tolgee/react todo app, and its Tolgee setup is the important part:
The detail that matters for this walkthrough is that the app runs in development mode - it's initialized with an apiKey, so DevTools() is active. In dev mode the SDK fetches translations straight from the Tolgee API (GET /v2/projects/{id}/translations/{language}, uncached) rather than from bundled files. That gives us a tight loop: anything the agent writes into Tolgee shows up in the running app on the next refresh - no export, no import, no rebuild. FormatIcu() handles ICU plurals and interpolation on top.
BackendFetch() is the production counterpart: with no apiKey present, it loads pre-published static JSON files (one per language) from a CDN path instead of calling the API. You wouldn't ship a dev API key to production - so in a real deployment you'd publish those files via Tolgee's Content Delivery. For this walkthrough, dev mode is what makes the agent's changes visible instantly.
Workflow A: adding strings for a new feature
We want a "Duplicate item" button on each todo. Because the agent is already in the editor and wired to Tolgee, we can ask it to do the whole thing: write the component and set up its localization, in one go:
You: Add a "Duplicate" button to each item in the todo list that duplicates that item. Use Tolgee for its label - create a key
duplicate-item-buttonwith the English value "Duplicate", machine-translate it to Czech, French, and German, tag ittodo-actionsto match the other item buttons, and add a short description noting it duplicates a single list item.
The agent edits the code, adding the button with the label wired to Tolgee from the start rather than as a hardcoded string it has to circle back and fix:
Then it turns to Tolgee, chaining several MCP tools:
Create the key -
duplicate-item-buttonwith the English base value.Run machine translation - a batch job targeting
cs,fr,de, then polls until it finishes.Tag the key - applies
todo-actions.Write context - stores the description so future translations (human or machine) know what "Duplicate" means here, avoiding the classic "duplicate = a copy vs. duplicate = the act of copying" ambiguity.
Refresh the app. Because dev mode pulls from the Tolgee API live, the button renders in whatever language the app is set to - the Czech, French, and German values the agent just generated are already there. Switch the language selector and watch it follow.
The point isn't that any single one of these steps is hard. It's that code and localization landed together, from one instruction - the agent wrote the component, created the key, translated it, tagged it, and described it, each an inspectable tool call rather than a black-box paste.
Workflow B: filling missing translations in bulk
New keys aren't the only gap. Over a project's life, keys accumulate faster than translations: someone adds an English string in a hurry, someone else adds a fifth language, and suddenly the coverage is patchy. This is where reading the project's stats and acting on them pays off.
Start by asking what's actually missing:
You: Which keys in this project are missing Czech, French, or German translations?
The agent reads the project's language statistics and searches keys by translation state, then reports the gaps - say, eight keys with no German, three missing French. Then act on all of them at once:
You: Machine-translate everything that's missing cs/fr/de. Skip keys that already have a value in those languages - don't overwrite existing translations.
The agent kicks off a batch MT job scoped to the untranslated keys and languages, waits for it to complete, and reports back. Because you told it to skip existing values, human-reviewed translations are left untouched - the job only fills holes.
Ask for the stats again and you'll see the coverage bars move to full. This is the kind of chore that's tedious to do by hand in the UI - select keys, pick languages, run the job, verify - and natural to express in one sentence to an agent that can see the same project you can.
A note on safety
The developer role can delete things, and the agent is acting on your real project. A few habits keep that comfortable:
Read before you write. Ask it to list or search first. It's a free way to confirm the agent is pointed at the right project and understands your intent before anything mutates.
Prefer a PAK. Scoping the key to one project means an over-eager agent physically cannot touch your other projects.
Know what's irreversible.
delete_keysanddelete_branchdon't have an undo. When you ask the agent to clean up, ask it to list exactly what it will delete first, and confirm.Keep the key out of your repo. The
X-API-Keyis a credential. Store it in your MCP client config or a secrets manager, not in committed files.Use branches for risky work. The MCP server can create and delete Tolgee branches — isolate a big restructuring on a branch the same way you would in git, and merge when you're happy.
What's next for the server
The MCP server is early, and two things are coming:
OAuth. Today you authenticate with a PAK or PAT in a header. OAuth is on the near-term roadmap, so clients can authorize against Tolgee without you minting and pasting a token by hand.
More roles than
developer. The/mcp/developerendpoint covers the developer surface: keys, translations, languages, tags, branches, batch operations. Alongside it we plan to add another endpoint for managing organizations and administering the server itself over MCP, so operations beyond a single project's content become agent-drivable too.
Wrapping up
The agent in your editor can now read and change your Tolgee project directly, one inspectable tool call at a time. The MCP server is what makes that possible: it gives the agent a typed view of what Tolgee can do, and the agent composes those tools into the workflow the task needs. In the example app, dev mode closes the loop - the strings the agent writes render in four languages on the next refresh.
For the full set of example prompts and recommended patterns, see the usage guide.
Links:
MCP server overview: docs.tolgee.io/platform/integrations/mcp_server/about
Setup guide: docs.tolgee.io/platform/integrations/mcp_server/setup
Usage guide: docs.tolgee.io/platform/integrations/mcp_server/usage
Example app: tolgee-js/testapps/react
@tolgee/reactdocs: docs.tolgee.io/js-sdk/integrations/react/installation


