<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Zw-awa</title>
    <description>The latest articles on Forem by Zw-awa (@zwawa).</description>
    <link>https://forem.com/zwawa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3890783%2F01d8e8f6-5c63-4057-8ca5-42b3e2fa4970.png</url>
      <title>Forem: Zw-awa</title>
      <link>https://forem.com/zwawa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/zwawa"/>
    <language>en</language>
    <item>
      <title>I Got Tired of Splitting My Brain Between Local AI and Remote SSH, So I Built ssh-session-mcp</title>
      <dc:creator>Zw-awa</dc:creator>
      <pubDate>Tue, 21 Apr 2026 14:44:43 +0000</pubDate>
      <link>https://forem.com/zwawa/i-got-tired-of-splitting-my-brain-between-local-ai-and-remote-ssh-so-i-built-ssh-session-mcp-d0e</link>
      <guid>https://forem.com/zwawa/i-got-tired-of-splitting-my-brain-between-local-ai-and-remote-ssh-so-i-built-ssh-session-mcp-d0e</guid>
      <description>&lt;p&gt;I spend a lot of time in environments where the real work does not happen on my laptop.&lt;/p&gt;

&lt;p&gt;The code editor is local. The AI assistant is local. But the target machine is often a remote Linux box, a board, a test host, or a GPU server.&lt;/p&gt;

&lt;p&gt;That creates a very annoying workflow gap.&lt;/p&gt;

&lt;p&gt;My AI assistant can edit files, reason about code, and suggest the exact fix. But the moment the next step involves SSH, I am back to doing manual relay work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;switch to another terminal&lt;/li&gt;
&lt;li&gt;connect to the remote host&lt;/li&gt;
&lt;li&gt;run the command myself&lt;/li&gt;
&lt;li&gt;inspect the output&lt;/li&gt;
&lt;li&gt;paste the result back into the AI chat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At that point, the AI is not really participating in the remote workflow. It is just advising from the sidelines.&lt;/p&gt;

&lt;p&gt;That is why I built and open sourced &lt;code&gt;ssh-session-mcp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgcjm26dj5asrqlv2llmu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgcjm26dj5asrqlv2llmu.png" alt="Main Image" width="780" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Is Not "SSH Is Hard"
&lt;/h2&gt;

&lt;p&gt;SSH itself is mature. The real problem is that most AI coding workflows still treat remote terminals as an external, human-only space.&lt;/p&gt;

&lt;p&gt;In practice, that causes several recurring issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Local AI and remote execution live in different worlds
&lt;/h3&gt;

&lt;p&gt;Your model can understand the repository and modify local files, but it cannot naturally step into the remote terminal where the service actually runs.&lt;/p&gt;

&lt;p&gt;So even when the AI knows exactly what should happen next, you still become the manual transport layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A terminal is stateful, but many integrations treat it like stateless RPC
&lt;/h3&gt;

&lt;p&gt;A remote shell is not just "run command, get output."&lt;/p&gt;

&lt;p&gt;It may currently be in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a normal shell prompt&lt;/li&gt;
&lt;li&gt;a password prompt&lt;/li&gt;
&lt;li&gt;a pager like &lt;code&gt;less&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;an editor&lt;/li&gt;
&lt;li&gt;a long-running command&lt;/li&gt;
&lt;li&gt;a streaming session&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the tool does not understand terminal state, it can easily make the wrong move.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Human and AI collaboration on the same remote session is awkward
&lt;/h3&gt;

&lt;p&gt;Real development is not fully manual or fully automated.&lt;/p&gt;

&lt;p&gt;Usually it looks more like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;let the AI inspect the environment&lt;/li&gt;
&lt;li&gt;take over manually for one or two commands&lt;/li&gt;
&lt;li&gt;hand control back to the AI&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without explicit coordination, that turns into input collisions and confusing terminal history.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Multi-host work is easy to get wrong
&lt;/h3&gt;

&lt;p&gt;One local repo can map to several remote targets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;board A&lt;/li&gt;
&lt;li&gt;board B&lt;/li&gt;
&lt;li&gt;a staging VM&lt;/li&gt;
&lt;li&gt;a shared Linux server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In those cases, "the command succeeded" is not enough. You also need confidence that it ran on the correct target.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ssh-session-mcp&lt;/code&gt; is a persistent SSH PTY session manager for MCP clients.&lt;/p&gt;

&lt;p&gt;The short version:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;it manages a real SSH PTY session&lt;/li&gt;
&lt;li&gt;an AI agent can operate it through MCP tools&lt;/li&gt;
&lt;li&gt;the user can observe and type into the same session from a browser terminal&lt;/li&gt;
&lt;li&gt;both sides share one actual terminal context&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the key design choice: not parallel lookalike sessions, but one shared PTY.&lt;/p&gt;

&lt;p&gt;That matters because state is the whole point. If the user and the AI are not looking at the same terminal state, they are not really collaborating.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu9vif4ho5c43byxnx2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu9vif4ho5c43byxnx2d.png" alt="Toolbar" width="564" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;ssh-session-mcp&lt;/code&gt; Does Right Now
&lt;/h2&gt;

&lt;p&gt;I have kept the scope intentionally narrow. This project focuses on the SSH transport/runtime layer, not on project-specific business logic.&lt;/p&gt;

&lt;p&gt;Current capabilities include:&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared SSH terminal
&lt;/h3&gt;

&lt;p&gt;The user and the AI share one PTY, so they see the same shell state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Browser terminal
&lt;/h3&gt;

&lt;p&gt;There is a local browser-based terminal for observation and manual takeover.&lt;/p&gt;

&lt;h3&gt;
  
  
  Input locking
&lt;/h3&gt;

&lt;p&gt;You can switch between &lt;code&gt;common&lt;/code&gt;, &lt;code&gt;user&lt;/code&gt;, and &lt;code&gt;claude/codex&lt;/code&gt; modes to avoid input conflicts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Safe vs full mode
&lt;/h3&gt;

&lt;p&gt;Safe mode blocks obviously dangerous commands, interactive programs, and commands that do not naturally terminate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intelligent command completion
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ssh-run&lt;/code&gt; does not rely on a naive fixed timeout. It combines prompt detection, idle timeout, and sentinel markers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Async command tracking
&lt;/h3&gt;

&lt;p&gt;Long-running commands can automatically transition to async mode and be polled later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diagnostics and line-based history
&lt;/h3&gt;

&lt;p&gt;I did not want this to become a black box, so the project includes session diagnostics and line-numbered history recall.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-device profiles
&lt;/h3&gt;

&lt;p&gt;You can manage multiple targets and named connections through configuration instead of constantly rewriting host/user settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Workflow I Wanted
&lt;/h2&gt;

&lt;p&gt;This is the kind of loop I wanted AI tools to support cleanly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-quick-connect -&amp;gt; ssh-run -&amp;gt; inspect output -&amp;gt; decide -&amp;gt; ssh-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v9py9jl9y4e43wi1dxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v9py9jl9y4e43wi1dxr.png" alt="Home" width="780" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the command is long-running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-run({ command: "apt update" })
-&amp;gt; async commandId

ssh-command-status({ commandId: "..." })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if I want to intervene manually, I should be able to type into the same terminal without rebuilding the whole session from scratch.&lt;/p&gt;

&lt;p&gt;That sounds simple, but it changes the experience a lot. The remote environment stops being a blind spot in the AI workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Did Not Build "Yet Another AI Platform"
&lt;/h2&gt;

&lt;p&gt;I think infrastructure projects get messy when they try to absorb too much.&lt;/p&gt;

&lt;p&gt;So I keep &lt;code&gt;ssh-session-mcp&lt;/code&gt; focused on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;sessions&lt;/li&gt;
&lt;li&gt;viewers&lt;/li&gt;
&lt;li&gt;targeting&lt;/li&gt;
&lt;li&gt;locks&lt;/li&gt;
&lt;li&gt;logging&lt;/li&gt;
&lt;li&gt;tool contracts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I am explicitly not trying to bake in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ROS workflows&lt;/li&gt;
&lt;li&gt;board-specific business logic&lt;/li&gt;
&lt;li&gt;domain prompts&lt;/li&gt;
&lt;li&gt;training pipelines&lt;/li&gt;
&lt;li&gt;project orchestration logic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those things belong outside this repo.&lt;/p&gt;

&lt;p&gt;I would rather have a small, reliable runtime layer than a bloated project that mixes transport, policy, and product-specific automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who This Is For
&lt;/h2&gt;

&lt;p&gt;I think this project is most useful if you work in one of these setups:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;embedded or board development&lt;/li&gt;
&lt;li&gt;remote Linux development&lt;/li&gt;
&lt;li&gt;GPU or VM-based development environments&lt;/li&gt;
&lt;li&gt;AI-assisted workflows where manual takeover still matters&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all your work happens locally, this may not be very interesting.&lt;/p&gt;

&lt;p&gt;But if you keep feeling the gap between "AI can edit my code" and "I still have to manually drive the remote machine," then this is exactly the gap I am trying to close.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;Install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ssh-session-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or build from source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Zw-awa/ssh-session-mcp.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ssh-session-mcp
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then configure &lt;code&gt;.env&lt;/code&gt; or &lt;code&gt;ssh-session-mcp.config.json&lt;/code&gt;, launch the runtime, and register it as an MCP server for your AI client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;I do not think the future of AI-assisted development is "the model does everything."&lt;/p&gt;

&lt;p&gt;I think the more realistic future is this:&lt;/p&gt;

&lt;p&gt;the model and the developer share better infrastructure.&lt;/p&gt;

&lt;p&gt;For remote development, that means SSH can no longer remain a manual side channel outside the workflow.&lt;/p&gt;

&lt;p&gt;That is what &lt;code&gt;ssh-session-mcp&lt;/code&gt; is trying to fix.&lt;/p&gt;

&lt;p&gt;Repo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://github.com/Zw-awa/ssh-session-mcp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you work on remote machines and have strong opinions about shared terminals, safety modes, session targeting, or human/AI handoff, I would genuinely like to hear them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>ssh</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
