{"id":105,"date":"2026-09-23T11:24:44","date_gmt":"2026-09-23T11:24:44","guid":{"rendered":"https:\/\/docs.latw.ai\/uncategorized\/mcp-server-2\/"},"modified":"2026-09-23T11:24:44","modified_gmt":"2026-09-23T11:24:44","slug":"mcp-server-2","status":"publish","type":"post","link":"https:\/\/docs.latw.ai\/pl\/latw-for-polylang\/mcp-server-2\/","title":{"rendered":"Translating from Claude and ChatGPT (MCP)"},"content":{"rendered":"<p><em>Available in LATW AI Translation for Polylang <strong>PRO<\/strong>.<\/em><\/p>\n<p>Everywhere else in this plugin, translating means sending your text to an AI engine and paying that<br \/>\nengine for the answer. The MCP server turns that around. You connect your site to the AI assistant<br \/>\nyou already use \u2014 Claude or ChatGPT \u2014 and translate from inside the conversation. The assistant<br \/>\nwrites the translation; the plugin puts it into Polylang.<\/p>\n<p><strong>There is no API bill.<\/strong> No key is used, no engine is called, and every translation made this way<br \/>\nshows a cost of $0.00 on the History screen. You are using the subscription you already pay for.<\/p>\n<p>MCP \u2014 Model Context Protocol \u2014 is the standard those assistants use to talk to outside systems.<br \/>\nSwitching the server on gives the assistant a set of tools: find untranslated pages, take one for<br \/>\ntranslation, send the translation back, look something up in your glossary.<\/p>\n<p>In practice a session looks like this:<\/p>\n<blockquote>\n<p><strong>You:<\/strong> What still needs translating into German?<\/p>\n<p><strong>Claude:<\/strong> Eleven pages have no German version. The most recently edited are <em>About<\/em>, <em>Shipping &amp;<br \/>\nReturns<\/em> and <em>Our Suppliers<\/em>.<\/p>\n<p><strong>You:<\/strong> Do the three of them.<\/p>\n<p><strong>Claude:<\/strong> <em>(takes each page, translates it, sends it back)<\/em> All three are translated and live.<br \/>\n<em>About<\/em> is at \/de\/uber-uns\/.<\/p>\n<\/blockquote>\n<h2>What you need before you start<\/h2>\n<ul>\n<li>An active <strong>PRO licence<\/strong>.<\/li>\n<li><strong>Polylang<\/strong>, with at least two languages set up, as for any other translation this plugin makes.<\/li>\n<li><strong>HTTPS.<\/strong> Assistants run on someone else&#8217;s servers and will not connect to an unencrypted site.<\/li>\n<li>A <strong>Claude<\/strong> or <strong>ChatGPT<\/strong> plan that allows custom connectors. On ChatGPT that means Plus, Pro,<br \/>\nBusiness, Enterprise or Edu \u2014 the free tier cannot add one.<\/li>\n<\/ul>\n<h2>Switching it on<\/h2>\n<ol>\n<li>Go to <strong>AI Translation \u2192 Settings \u2192 MCP<\/strong>.<\/li>\n<li>Turn on <strong>MCP server<\/strong>.<\/li>\n<li>Press <strong>Generate token<\/strong>. The token is the password to this door \u2014 anyone holding it can read and<br \/>\ntranslate your site&#8217;s content.<\/li>\n<li>Decide what the assistant may reach, under <strong>What the assistant may do<\/strong>. Posts and pages are<br \/>\nalways available. Status and costs, and the glossary, are on by default; interface strings and<br \/>\ncategories are off until you want them.<\/li>\n<li>Press <strong>Save Changes<\/strong>, then <strong>Test connection<\/strong>. That check calls the server the same way an<br \/>\nassistant would and tells you plainly if something between the internet and WordPress is in the<br \/>\nway.<\/li>\n<\/ol>\n<p>The screen then shows two addresses. Which one you use depends on the application.<\/p>\n<h2>Connecting Claude<\/h2>\n<p><strong>Claude Desktop and claude.ai.<\/strong> Open <strong>Settings \u2192 Connectors \u2192 Add custom connector<\/strong>, give it a<br \/>\nname, and paste the <strong>Address (token in URL)<\/strong> from the MCP tab. Press <strong>Show<\/strong> next to the field<br \/>\nfirst \u2014 the screen masks it until you do. There is nothing else to fill in: the token is part of the<br \/>\naddress.<\/p>\n<p><strong>Claude Code.<\/strong> The MCP tab shows the exact command, ready to copy:<\/p>\n<pre><code>claude mcp add my-site https:\/\/example.com\/wp-json\/latw-mcp\/v1\/http --transport http --header \"Authorization: Bearer YOUR_TOKEN\"<\/code><\/pre>\n<p>Run it in a terminal, then <code>\/mcp<\/code> inside Claude Code to confirm the site is listed.<\/p>\n<h2>Connecting ChatGPT<\/h2>\n<p>Custom connectors are hidden until you switch developer mode on, so this is two trips into Settings.<\/p>\n<p><strong>First, switch developer mode on.<\/strong> Open <strong>Settings \u2192 Security and login<\/strong>, find <strong>Developer mode<\/strong><br \/>\nand turn it on.<\/p>\n<p><strong>Then add the connector.<\/strong> Open <strong>Settings \u2192 Plugins \u2192 Browse plugins<\/strong> and press the <strong>+<\/strong> in the<br \/>\ntop right corner. Fill the form in:<\/p>\n<ul>\n<li><strong>Name<\/strong> \u2014 whatever you want to see in the conversation, for example your site&#8217;s name.<\/li>\n<li><strong>Address<\/strong> \u2014 the <strong>Address (token in URL)<\/strong> from the MCP tab.<\/li>\n<li><strong>Authentication<\/strong> \u2014 <strong>No Auth<\/strong>. The token is already part of the address, so there is nothing<br \/>\nelse to fill in.<\/li>\n<li>Tick <strong>I understand and want to continue<\/strong>, then press <strong>Create<\/strong>.<\/li>\n<\/ul>\n<p>ChatGPT loads the connector, which takes a moment, and then shows <strong>Connect<\/strong>. Press it, and the<br \/>\nsite&#8217;s tools are available in the conversation.<\/p>\n<h2>Asking for a translation<\/h2>\n<p>Once connected, ask in plain language. The assistant has the tools; you do not need to name them.<\/p>\n<ul>\n<li><em>&#8220;What pages have no French translation yet?&#8221;<\/em><\/li>\n<li><em>&#8220;Translate the About page into German and French.&#8221;<\/em><\/li>\n<li><em>&#8220;The pricing page changed \u2014 update the Polish version.&#8221;<\/em><\/li>\n<li><em>&#8220;How much have translations cost this month?&#8221;<\/em><\/li>\n<li><em>&#8220;Show me the German version of the pricing page \u2014 does it read naturally?&#8221;<\/em><\/li>\n<li><em>&#8220;The Polish About page says &#8216;Zacznij zakupy&#8217; on the button. Change it to &#8216;Przejd\u017a do zakup\u00f3w&#8217;.&#8221;<\/em><\/li>\n<li><em>&#8220;What was the last thing translated?&#8221;<\/em><\/li>\n<li><em>&#8220;Change the Polish address of the About page to o-nas-firmy.&#8221;<\/em><\/li>\n<li><em>&#8220;Translate only the SEO title and description of the About page into Polish.&#8221;<\/em><\/li>\n<\/ul>\n<p>The translation is written into Polylang exactly where the plugin would have written it. It appears<br \/>\nin <strong>AI Translation \u2192 History<\/strong>, in Polylang&#8217;s own language switcher, and on the front end, and you<br \/>\ncan edit it afterwards in the block editor like any other translation.<\/p>\n<p>Which parts of a page the assistant is handed \u2014 the content, the custom fields, the SEO title and<br \/>\ndescription \u2014 is decided by this plugin&#8217;s own settings, under <strong>Settings \u2192 Translation<\/strong>, and the<br \/>\nrules are the same however you translate.<\/p>\n<h2>Reviewing and correcting a translation<\/h2>\n<p>You do not have to accept a translation as it came out, and you do not have to redo the whole page<br \/>\nto change one line.<\/p>\n<p>Ask to see it, and the assistant reads the current translation field by field beside the source it<br \/>\ncame from:<\/p>\n<blockquote>\n<p><strong>You:<\/strong> Show me the Polish About page next to the original.<\/p>\n<p><strong>Claude:<\/strong> <em>(lists each piece)<\/em> The heading is &#8220;O nas&#8221;, the intro is \u2026, the button says &#8220;Zacznij<br \/>\nzakupy&#8221;.<\/p>\n<p><strong>You:<\/strong> The button should say &#8220;Przejd\u017a do zakup\u00f3w&#8221;.<\/p>\n<p><strong>Claude:<\/strong> Changed. The rest of the page is untouched.<\/p>\n<\/blockquote>\n<p>Only the line you asked about is rewritten. Everything else keeps the wording it already had,<br \/>\nincluding any corrections you made by hand in the editor.<\/p>\n<p>Two things are worth knowing:<\/p>\n<ul>\n<li><strong>A page translated by hand from scratch cannot be listed this way.<\/strong> This plugin keeps no record<br \/>\nof which text produced which translation unless it made the translation itself, so there is<br \/>\nnothing to line up, and the assistant will say so rather than guess.<\/li>\n<li><strong>A first translation is all-or-nothing.<\/strong> Until a page has a translation, every field has to be<br \/>\nfilled in one go \u2014 there is nothing to keep for the ones left out, so they would be published<br \/>\nempty. The assistant is told this and will not half-translate a page by accident.<\/li>\n<\/ul>\n<h2>Addresses of translated pages<\/h2>\n<p>When Polylang creates a translation it builds its address from the translated title, so <em>About<\/em><br \/>\nbecomes <code>\/pl\/o-nas\/<\/code> on its own. That is usually what you want, and occasionally not \u2014 a title that<br \/>\ntranslates to the same words, or a page whose heading and URL should read differently.<\/p>\n<p>You can ask for a different one, either while translating or long afterwards:<\/p>\n<blockquote>\n<p><strong>You:<\/strong> Translate the About page into Polish, and make the address \/pl\/o-nas-firmy\/.<\/p>\n<\/blockquote>\n<blockquote>\n<p><strong>You:<\/strong> Change the Polish address of the About page to poznaj-nasza-firme.<\/p>\n<\/blockquote>\n<p>Only the translation moves. The original page keeps its own address, and so does every other<br \/>\nlanguage. If the address you ask for is already used by another page in that language, WordPress<br \/>\nappends a number and the assistant tells you which address it actually got.<\/p>\n<p>For <strong>posts<\/strong>, changing the address of something already published is safe: WordPress remembers the<br \/>\nold address and sends anyone using it to the new one, exactly as it does when you rename a post in<br \/>\nthe editor.<\/p>\n<p><strong>Pages are the exception.<\/strong> WordPress only keeps old addresses for non-hierarchical content, and<br \/>\npages are hierarchical \u2014 so the old address of a page simply stops working, and any link pointing at<br \/>\nit lands on a 404. If the page was already published and linked to, add a redirect yourself.<\/p>\n<h2>What it will not do<\/h2>\n<p>Be clear about this before you promise it to anyone:<\/p>\n<ul>\n<li><strong>It is not bulk translation.<\/strong> The assistant works page by page, in a conversation, and long<br \/>\npages use up a lot of it. For dozens of posts, use <strong>Automatic Translation<\/strong> and pay the API bill \u2014<br \/>\nthat is what it is for. This is for the pages you care about individually.<\/li>\n<li><strong>The quality is the assistant&#8217;s, not the plugin&#8217;s.<\/strong> Your <strong>Translation Prompt<\/strong> and <strong>Website<br \/>\nDescription<\/strong> are handed over as guidance, but nothing enforces them. An assistant that decides to<br \/>\nparaphrase will paraphrase.<\/li>\n<li><strong>The glossary is advice here, not a rule.<\/strong> Your terms are sent with every job and assistants<br \/>\nfollow them well, but the plugin cannot check the result the way it does on its own pipeline.<\/li>\n<li><strong>There is no &#8220;outdated&#8221; list.<\/strong> <em>Find content to translate<\/em> can tell you what has no translation<br \/>\nyet, but not what changed since the last one \u2014 ask the assistant to read a specific page with<br \/>\n<em>latw_get_translation<\/em> instead.<\/li>\n<li><strong>A conversation can stop halfway.<\/strong> If it does, the page is left with an open job. Ask the<br \/>\nassistant to <em>&#8220;list open translation jobs&#8221;<\/em> and either finish or cancel them; open jobs also show<br \/>\nas <code>awaiting_mcp<\/code> on the History screen.<\/li>\n<li><strong>One token for the whole site.<\/strong> There is no per-person access and no list of connected<br \/>\napplications. Generating a new token disconnects everything using the old one.<\/li>\n<\/ul>\n<h2>About the token<\/h2>\n<p>The token is shown masked, and <strong>Show<\/strong> reveals it \u2014 you will need to read it back when you connect<br \/>\na second application.<\/p>\n<p>The two addresses differ in more than convenience. The one with the token in the URL is the easy<br \/>\none, and it is what Claude Desktop and ChatGPT need, but a secret in an address ends up in your<br \/>\nserver&#8217;s access logs and in the browser history of whoever pasted it. The address using the<br \/>\n<code>Authorization<\/code> header keeps the token out of both, and is worth using wherever the application<br \/>\nsupports it.<\/p>\n<p>Either way: treat the token like an administrator password, and press <strong>Generate a new token<\/strong> the<br \/>\nmoment you think someone else has seen it.<\/p>\n<p>The connected assistant acts as the WordPress user who generated the token, with that user&#8217;s<br \/>\npermissions. If that account is deleted or loses its administrator role, the token stops working.<\/p>\n<h2>When something goes wrong<\/h2>\n<p><strong>Test connection<\/strong> on the MCP tab is the first thing to try \u2014 it separates &#8220;the plugin is fine and<br \/>\nyour assistant is misconfigured&#8221; from &#8220;nothing can reach this site at all&#8221;.<\/p>\n<table>\n<thead>\n<tr>\n<th>What you see<\/th>\n<th>What it usually means<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>The assistant says it cannot reach the server<\/td>\n<td>The address is wrong, the server is switched off, or the site is not on HTTPS.<\/td>\n<\/tr>\n<tr>\n<td>Test connection says the token did not arrive<\/td>\n<td>Your host strips the <code>Authorization<\/code> header before PHP sees it. Use the address with the token in the URL instead.<\/td>\n<\/tr>\n<tr>\n<td>Test connection cannot reach the site at all<\/td>\n<td>A firewall or a security plugin is blocking <code>\/wp-json\/<\/code>. Allow <code>\/wp-json\/latw-mcp\/<\/code> through.<\/td>\n<\/tr>\n<tr>\n<td>A 404 from the address<\/td>\n<td>The server is switched off, or the licence is not active.<\/td>\n<\/tr>\n<tr>\n<td>A 401<\/td>\n<td>The token is wrong \u2014 copy it again from the MCP tab.<\/td>\n<\/tr>\n<tr>\n<td>The assistant lists no tools<\/td>\n<td>The licence expired, or every tool group was switched off.<\/td>\n<\/tr>\n<tr>\n<td>Rows stuck at <code>awaiting_mcp<\/code><\/td>\n<td>A conversation ended mid-job. Ask the assistant to list and cancel open jobs.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The <strong>AI Translation \u2192 Logs<\/strong> page records what happened on this site&#8217;s side, and<br \/>\n<strong>Settings \u2192 Advanced \u2192 Debug Mode<\/strong> adds the detail.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Available in LATW AI Translation for Polylang PRO. Everywhere else in this plugin, translating means sending your text to an AI engine and paying that engine\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_latwm_translated_slug":"","footnotes":""},"categories":[17],"tags":[],"class_list":["post-105","post","type-post","status-publish","format-standard","hentry","category-latw-for-polylang"],"_links":{"self":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts\/105","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/comments?post=105"}],"version-history":[{"count":0,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts\/105\/revisions"}],"wp:attachment":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/media?parent=105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/categories?post=105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/tags?post=105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}