<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Cloud devops]]></title><description><![CDATA[Cloud devops]]></description><link>https://clodevops.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1757930359301/bc851865-eeee-45bd-aec0-70920bc45fea.png</url><title>Cloud devops</title><link>https://clodevops.com</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 02:15:31 GMT</lastBuildDate><atom:link href="https://clodevops.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[MCP, SSE, and HTTPS: Why Claude Code Fails to Connect — and How to Fix It]]></title><description><![CDATA[A deep dive into the Model Context Protocol, SSE and HTTP/2 issues, Anthropic’s transition to WebSocket, and the nginx configuration that keeps it all running.
What is MCP
Model Context Protocol (MCP) is the bridge that allows Claude Code to connect ...]]></description><link>https://clodevops.com/mcp-sse-and-https-why-claude-code-fails-to-connect-and-how-to-fix-it</link><guid isPermaLink="true">https://clodevops.com/mcp-sse-and-https-why-claude-code-fails-to-connect-and-how-to-fix-it</guid><category><![CDATA[mcp server]]></category><category><![CDATA[claude-code]]></category><category><![CDATA[mcp]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Anton Sun]]></dc:creator><pubDate>Wed, 15 Oct 2025 22:04:44 GMT</pubDate><content:encoded><![CDATA[<p><strong>A deep dive into the Model Context Protocol, SSE and HTTP/2 issues, Anthropic’s transition to WebSocket, and the nginx configuration that keeps it all running.</strong></p>
<h2 id="heading-what-is-mcp"><strong>What is MCP</strong></h2>
<p><strong>Model Context Protocol (MCP)</strong> is the bridge that allows Claude Code to connect external tools and services.</p>
<p>It supports two transport modes:</p>
<ul>
<li><p>stdio — standard input/output, good for local development</p>
</li>
<li><p>sse — <strong>Server-Sent Events</strong>, used for remote or networked access</p>
</li>
</ul>
<p>Most MCP connection issues aren’t caused by code, but by infrastructure details: HTTP protocol quirks, nginx defaults, or strict schema validation recently introduced by Anthropic.</p>
<hr />
<h2 id="heading-common-symptoms"><strong>Common Symptoms</strong></h2>
<p>Running:</p>
<pre><code class="lang-bash">claude mcp list
</code></pre>
<p>returns:</p>
<pre><code class="lang-bash">infonux: https://example.com/mcp_server (HTTP) - ✗ Failed to connect
</code></pre>
<p>Logs show:</p>
<pre><code class="lang-bash">[Error] Does not adhere to MCP server configuration schema
</code></pre>
<p>Meanwhile:</p>
<ul>
<li><p>nginx responds correctly</p>
</li>
<li><p>curl returns valid SSE events</p>
</li>
<li><p>HTTPS and tokens work normally</p>
</li>
</ul>
<p>If all that is true, the issue isn’t networking — it’s configuration and protocol compatibility.</p>
<hr />
<h2 id="heading-why-https-sometimes-breaks-everything"><strong>Why HTTPS Sometimes Breaks Everything</strong></h2>
<p>SSE only works over <strong>HTTP/1.1</strong>.</p>
<p>HTTP/2 uses multiplexing, which interrupts persistent streams.</p>
<p>When that happens, MCP CLI can’t maintain the connection and shows:</p>
<pre><code class="lang-bash">✗ Failed to connect
</code></pre>
<p><strong>Quick summary:</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Protocol</strong></td><td><strong>Works with SSE</strong></td></tr>
</thead>
<tbody>
<tr>
<td>HTTP/1.1</td><td>✅ Yes</td></tr>
<tr>
<td>HTTP/2</td><td>❌ No</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-sse-and-anthropics-shift-to-websocket"><strong>SSE and Anthropic’s Shift to WebSocket</strong></h2>
<p>In <strong>spring 2025</strong>, Anthropic began phasing out the classic <strong>HTTP + Server-Sent Events (SSE)</strong> transport in favor of new mechanisms:</p>
<ul>
<li><p><strong>Streamable HTTP</strong>, still MCP-compatible and supporting bidirectional traffic;</p>
</li>
<li><p><strong>WebSocket</strong>, which provides a more stable, persistent, and transport-independent connection.</p>
</li>
</ul>
<p>The updated MCP specification (March 2025) introduced:</p>
<ul>
<li><p>full <strong>JSON-RPC</strong> bidirectional support,</p>
</li>
<li><p>compatibility with standard HTTP servers (no extra SSE endpoint required),</p>
</li>
<li><p>fewer dependencies on proxy/CDN quirks,</p>
</li>
<li><p>no need to maintain two simultaneous channels.</p>
</li>
</ul>
<details>
<summary>Why WebSocket Makes Sense</summary>

WebSocket enables true two-way communication and eliminates HTTP transport limitations.<br />It fits the interactive nature of modern AI interfaces and collaborative applications.<br />Anthropic maintains SDK compatibility, allowing a gradual migration without breaking existing infrastructure.

</details>

<p>SSE remains temporarily supported but is now officially <strong>deprecated</strong>.</p>
<p>Future SDKs (starting with 2025 releases) use WebSocket as the default transport, with <strong>Streamable HTTP</strong> available for backward compatibility.</p>
<hr />
<h2 id="heading-minimal-working-mcp-configuration"><strong>Minimal Working MCP Configuration</strong></h2>
<p><strong>Incorrect:</strong></p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"type"</span>: <span class="hljs-string">"sse"</span>,
  <span class="hljs-string">"command"</span>: <span class="hljs-string">"http://localhost:3010"</span>,
  <span class="hljs-string">"args"</span>: [],
  <span class="hljs-string">"env"</span>: {},
  <span class="hljs-string">"headers"</span>: { <span class="hljs-string">"Authorization"</span>: <span class="hljs-string">"Bearer TOKEN"</span> }
}
</code></pre>
<p><strong>Correct:</strong></p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"type"</span>: <span class="hljs-string">"sse"</span>,
  <span class="hljs-string">"url"</span>: <span class="hljs-string">"http://localhost:3010"</span>,
  <span class="hljs-string">"headers"</span>: { <span class="hljs-string">"Authorization"</span>: <span class="hljs-string">"Bearer TOKEN"</span> }
}
</code></pre>
<p><strong>Key differences:</strong></p>
<ul>
<li><p>url replaces command</p>
</li>
<li><p>args and env are removed</p>
</li>
<li><p>headers are optional</p>
</li>
</ul>
<p>Anthropic now enforces strict JSON schema validation — if the structure doesn’t match, MCP simply refuses to connect.</p>
<hr />
<h2 id="heading-nginx-configuration-for-https-and-sse"><strong>nginx Configuration for HTTPS and SSE</strong></h2>
<p>HTTPS works perfectly if the server is configured correctly for SSE.</p>
<p>The essentials: use HTTP/1.1, enable IPv6, and extend timeouts.</p>
<p><strong>Minimal example:</strong></p>
<pre><code class="lang-bash">server {
    listen 8443 ssl;           <span class="hljs-comment"># HTTP/1.1 only, no http2</span>
    listen [::]:8443 ssl;      <span class="hljs-comment"># IPv6 required</span>

    ssl_certificate     /etc/letsencrypt/live/your-domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain/privkey.pem;

    location / {
        proxy_pass http://localhost:3020/;
        proxy_http_version 1.1;       <span class="hljs-comment"># required</span>
        proxy_set_header Connection <span class="hljs-string">""</span>;
        proxy_buffering off;          <span class="hljs-comment"># must be disabled for SSE</span>
        proxy_read_timeout 86400;     <span class="hljs-comment"># long-lived connection</span>
    }
}
</code></pre>
<p><strong>Avoid:</strong></p>
<pre><code class="lang-bash">listen 443 ssl http2;     <span class="hljs-comment"># breaks SSE</span>
proxy_buffering on;       <span class="hljs-comment"># interrupts the stream</span>
listen 8443 ssl;          <span class="hljs-comment"># missing IPv6 — Claude Code won't connect</span>
</code></pre>
<details>
<summary>More on nginx and SSL setup</summary>
Use a dedicated HTTPS port (e.g., 8443) and force proxy_http_version 1.1.
Disable buffering, gzip, and short timeouts.
A full production configuration is available in the official MCP Server Template repository.
</details>

<hr />
<h2 id="heading-connection-testing"><strong>Connection Testing</strong></h2>
<p>Test the SSE stream manually:</p>
<pre><code class="lang-bash">curl -N -H <span class="hljs-string">"Accept: text/event-stream"</span> \
  -H <span class="hljs-string">"Authorization: Bearer TOKEN"</span> \
  https://your-domain.com:8443/sse
</code></pre>
<p>Expected output:</p>
<pre><code class="lang-bash">event: endpoint
data: /messages?sessionId=template-xxx
</code></pre>
<p>If that works, check via CLI:</p>
<pre><code class="lang-bash">claude mcp list
</code></pre>
<p>Result:</p>
<pre><code class="lang-bash">✓ Connected
</code></pre>
<hr />
<h2 id="heading-security-and-alternatives"><strong>Security and Alternatives</strong></h2>
<p>If exposing a public port isn’t ideal:</p>
<pre><code class="lang-bash">ssh -L 3020:localhost:3020 user@your-server.com -N &amp;
</code></pre>
<p>Then connect locally:</p>
<pre><code class="lang-bash">claude mcp add my-server \
  http://localhost:3020/sse \
  --transport sse \
  --header <span class="hljs-string">"Authorization: Bearer TOKEN"</span>
</code></pre>
<p>Recommendations:</p>
<ul>
<li><p>never use HTTP in production</p>
</li>
<li><p>rotate tokens regularly</p>
</li>
<li><p>monitor logs for unusual activity</p>
</li>
<li><p>use VPN or SSH tunnels for private setups</p>
</li>
</ul>
<hr />
<h2 id="heading-summary"><strong>Summary</strong></h2>
<ol>
<li><p><strong>HTTPS works</strong> if:</p>
<ul>
<li><p>you use <strong>HTTP/1.1</strong>,</p>
</li>
<li><p>IPv6 is enabled,</p>
</li>
<li><p>buffering is disabled,</p>
</li>
<li><p>timeouts are long enough.</p>
</li>
</ul>
</li>
<li><p><strong>HTTP/2 is incompatible</strong> with SSE.</p>
</li>
<li><p><strong>Anthropic is migrating</strong> from SSE to <strong>WebSocket</strong> and <strong>Streamable HTTP</strong>.</p>
</li>
<li><p><strong>“Failed to connect”</strong> errors usually mean configuration issues, not network problems.</p>
</li>
<li><p><strong>curl</strong> remains the most reliable diagnostic tool.</p>
</li>
</ol>
<hr />
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>MCP runs reliably over HTTPS — as long as the server doesn’t interfere with the SSE stream.</p>
<p>Anthropic’s move to WebSocket simplifies the protocol, improves stability, and aligns with modern real-time AI communication standards.</p>
<p>Stick to HTTP/1.1, follow the schema, and configure nginx carefully — the rest will just work.</p>
<hr />
<h2 id="heading-further-reading"><strong>Further Reading</strong></h2>
<ul>
<li><p><a target="_blank" href="https://modelcontextprotocol.io/">Official MCP Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/modelcontextprotocol/typescript-sdk">MCP SDK (TypeScript)</a></p>
</li>
<li><p><a target="_blank" href="https://claude.ai/docs">Anthropic Claude Code Docs</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events">Server-Sent Events vs WebSocket – MDN Overview</a></p>
</li>
<li><p><a target="_blank" href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html">nginx Proxying and HTTP/2 Limitations</a></p>
</li>
</ul>
<hr />
<p><strong>Full nginx configuration and MCP Server Template:</strong></p>
<p><a target="_blank" href="https://github.com/modelcontextprotocol/typescript-sdk">github.com/modelcontextprotocol/typescript-sdk</a></p>
]]></content:encoded></item><item><title><![CDATA[Magento Admin Reset Password: Common Bugs and Fixes]]></title><description><![CDATA[Password recovery for the Magento admin panel often encounters several issues caused by a few bugs. Here's a concise overview and their solutions:
Password reset link includes an extra pathThe URL contains an unnecessary /admin segment after the main...]]></description><link>https://clodevops.com/magento-admin-reset-password-common-bugs-and-fixes</link><guid isPermaLink="true">https://clodevops.com/magento-admin-reset-password-common-bugs-and-fixes</guid><category><![CDATA[Magento]]></category><category><![CDATA[adobe commerce]]></category><category><![CDATA[patches]]></category><dc:creator><![CDATA[Anton Sun]]></dc:creator><pubDate>Sat, 19 Oct 2024 07:20:12 GMT</pubDate><content:encoded><![CDATA[<p>Password recovery for the Magento admin panel often encounters several issues caused by a few bugs. Here's a concise overview and their solutions:</p>
<p><strong>Password reset link includes an extra path</strong><br />The URL contains an unnecessary <code>/admin</code> segment after the main domain, e.g.:<br /><code>http://magento.local/admin/admin_123456/admin/auth/resetpassword/key/xxxxxxxxxx/?id=1&amp;token=yyyyyyyy</code><br />Solution: Apply the patch suggested in <a target="_blank" href="https://github.com/magento/magento2/issues/35667#issuecomment-1943505361">this comment</a>.<br />Note: This issue exists in Magento 2.4.6 but has been fixed in version 2.4.7.</p>
<p><strong>Missing password reset form</strong><br />This issue is documented <a target="_blank" href="https://github.com/magento/magento2/issues/13349">here</a>. After upgrading Magento, the form might disappear, even with all custom modules disabled. A patch is needed to resolve this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729319949852/71584df4-b70e-4dec-95b1-3392a7906122.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-php">diff --git a/view/adminhtml/layout/adminhtml_auth_resetpassword.xml b/view/adminhtml/layout/adminhtml_auth_resetpassword.xml
index <span class="hljs-number">3</span>ee2rd.<span class="hljs-number">.8349152</span> <span class="hljs-number">111644</span>
--- a/view/adminhtml/layout/adminhtml_auth_resetpassword.xml    <span class="hljs-number">2024</span><span class="hljs-number">-10</span><span class="hljs-number">-16</span> <span class="hljs-number">23</span>:<span class="hljs-number">10</span>:<span class="hljs-number">32.714755233</span> +<span class="hljs-number">0200</span>
+++ b/view/adminhtml/layout/adminhtml_auth_resetpassword.xml    <span class="hljs-number">2024</span><span class="hljs-number">-10</span><span class="hljs-number">-16</span> <span class="hljs-number">23</span>:<span class="hljs-number">11</span>:<span class="hljs-number">13.808563121</span> +<span class="hljs-number">0200</span>

@@ <span class="hljs-number">-9</span>,<span class="hljs-number">7</span> +<span class="hljs-number">9</span>,<span class="hljs-number">7</span> @@
     &lt;update handle=<span class="hljs-string">"admin_login"</span> /&gt;
     &lt;body&gt;
         &lt;referenceContainer name=<span class="hljs-string">"login.content"</span>&gt;
-            &lt;block <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">Magento</span>\<span class="hljs-title">Backend</span>\<span class="hljs-title">Block</span>\<span class="hljs-title">Template</span>" <span class="hljs-title">name</span>="<span class="hljs-title">content</span>" <span class="hljs-title">template</span>="<span class="hljs-title">Magento_User</span>::<span class="hljs-title">admin</span>/<span class="hljs-title">resetforgottenpassword</span>.<span class="hljs-title">phtml</span>" /&gt;
+            &lt;<span class="hljs-title">block</span> <span class="hljs-title">class</span>="<span class="hljs-title">Magento</span>\<span class="hljs-title">Backend</span>\<span class="hljs-title">Block</span>\<span class="hljs-title">Template</span>" <span class="hljs-title">name</span>="<span class="hljs-title">content</span>.<span class="hljs-title">reset</span>.<span class="hljs-title">password</span>" <span class="hljs-title">template</span>="<span class="hljs-title">Magento_User</span>::<span class="hljs-title">admin</span>/<span class="hljs-title">resetforgottenpassword</span>.<span class="hljs-title">phtml</span>" /&gt;
         &lt;/<span class="hljs-title">referenceContainer</span>&gt;
     &lt;/<span class="hljs-title">body</span>&gt;
 &lt;/<span class="hljs-title">page</span>&gt;</span>
</code></pre>
<p>Add this into composer.json:</p>
<pre><code class="lang-php"><span class="hljs-string">"extra"</span>: {
    <span class="hljs-string">"magento-force"</span>: <span class="hljs-string">"override"</span>,
    <span class="hljs-string">"composer-exit-on-patch-failure"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"patches"</span>: {
        <span class="hljs-string">"magento/module-user"</span>: {
             <span class="hljs-string">"Reset password form for admin"</span>: <span class="hljs-string">"patches/composer/admin_password_reset_form.patch"</span>,
        }
    }
},
</code></pre>
<p><strong>Expired password reset link</strong><br />Modifying the form block leads to the error: "Your password reset link has expired." This occurs because the token is not added to the form.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729319413533/ea08d964-7d6f-4940-99de-e9b31e0fcc86.png" alt class="image--center mx-auto" /></p>
<p>Another patch is required to fix this issue.</p>
<pre><code class="lang-php">
--- /dev/<span class="hljs-literal">null</span>
+++ ../Controller/Adminhtml/Auth/ResetPassword.php
@@ <span class="hljs-number">-24</span>,<span class="hljs-number">7</span> +<span class="hljs-number">24</span>,<span class="hljs-number">7</span> @@

             <span class="hljs-keyword">$this</span>-&gt;_view-&gt;loadLayout();

-            $content = <span class="hljs-keyword">$this</span>-&gt;_view-&gt;getLayout()-&gt;getBlock(<span class="hljs-string">'content'</span>);
+            $content = <span class="hljs-keyword">$this</span>-&gt;_view-&gt;getLayout()-&gt;getBlock(<span class="hljs-string">'content.reset.password'</span>);
             <span class="hljs-keyword">if</span> ($content) {
                 $content-&gt;setData(<span class="hljs-string">'user_id'</span>, $userId)-&gt;setData(<span class="hljs-string">'reset_password_link_token'</span>, $passwordResetToken);
</code></pre>
<pre><code class="lang-php"><span class="hljs-string">"extra"</span>: {
    <span class="hljs-string">"magento-force"</span>: <span class="hljs-string">"override"</span>,
    <span class="hljs-string">"composer-exit-on-patch-failure"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"patches"</span>: {
        <span class="hljs-string">"magento/module-user"</span>: {
            <span class="hljs-string">"fix admin post reset"</span>: <span class="hljs-string">"patches/composer/magento-module-user-controller-adminhtml-auth-resetpassword-php.patch"</span>
        }
    }
},
</code></pre>
<p><strong>Missing 'id' parameter</strong><br />Sometimes the password reset link leads to an "expired link" message due to a missing <code>id</code> parameter in the file:<br /><code>vendor/magento/module-user/view/adminhtml/templates/admin/resetforgottenpassword.phtml</code>:</p>
<pre><code class="lang-php">&lt;form method=<span class="hljs-string">"post"</span> data-mage-init=<span class="hljs-string">'{"form": {}, "validation": {}}'</span>
      action=<span class="hljs-string">"&lt;?= <span class="hljs-subst">$block</span>-&gt;escapeUrl(
          <span class="hljs-subst">$block</span>-&gt;getUrl(
              '*/auth/resetpasswordpost',
              ['_query' =&gt; ['id' =&gt; <span class="hljs-subst">$block</span>-&gt;getUserId(), 'token' =&gt; <span class="hljs-subst">$block</span>-&gt;getResetPasswordLinkToken()]]
          )
      ) ?&gt;"</span> id=<span class="hljs-string">"reset-password-form"</span> autocomplete=<span class="hljs-string">"off"</span>&gt;
</code></pre>
<p>These issues require applying several patches to ensure the password recovery function works correctly in the Magento admin panel.</p>
]]></content:encoded></item></channel></rss>