aiterm-mcp 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -8,6 +8,8 @@
8
8
  [![npm](https://img.shields.io/npm/v/aiterm-mcp.svg)](https://www.npmjs.com/package/aiterm-mcp)
9
9
  [![node](https://img.shields.io/node/v/aiterm-mcp)](https://nodejs.org)
10
10
  [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
11
+ [![npm downloads](https://img.shields.io/npm/dm/aiterm-mcp.svg)](https://www.npmjs.com/package/aiterm-mcp)
12
+ [![install size](https://packagephobia.com/badge?p=aiterm-mcp)](https://packagephobia.com/result?p=aiterm-mcp)
11
13
 
12
14
  > *(English: [README.md](README.md))*
13
15
 
@@ -15,6 +17,31 @@
15
17
 
16
18
  `pty_open` / `pty_send` / `pty_read` / `pty_key` / `pty_close` / `pty_list` の 6 ツールだけ。バックエンドは tmux なので、MCP サーバや AI クライアントが再起動してもセッションは生き残る。
17
19
 
20
+ ## クイックスタート(約60秒)
21
+
22
+ Claude Code なら 1 コマンドで登録 — clone もビルドも不要、`npx` が毎回取得して起動する:
23
+
24
+ ```bash
25
+ claude mcp add --scope user --transport stdio aiterm -- npx -y aiterm-mcp
26
+ ```
27
+
28
+ Claude Code を再起動して、接続を確認:
29
+
30
+ ```bash
31
+ /mcp # aiterm が connected・6 ツール公開、と出る
32
+ ```
33
+
34
+ 最初のセッション — 4 回の呼び出しで、1 個の永続端末:
35
+
36
+ ```text
37
+ pty_open() → { session_id: "t1", attach: "tmux -S … attach -t t1" }
38
+ pty_send("t1", "echo hello") → PTY にコマンドを送る
39
+ pty_read("t1", { wait: true }) → "hello" (トークン削減・完了検出つき)
40
+ pty_close("t1") → 端末を解放
41
+ ```
42
+
43
+ これだけ。`t1` の端末は本物で永続 — `ssh`・`docker exec`・REPL は、そこへ `pty_send` で打ち込む“ただのテキスト”([なぜ](#なぜ))。インストールも不要にしたいなら、どの MCP クライアントからでも stdio で `npx -y aiterm-mcp` を起動するだけ。
44
+
18
45
  ## インストール
19
46
 
20
47
  npm に公開済み。clone もビルドも不要:
@@ -41,6 +68,43 @@ pty_send(id, "uname -a") → リモートで実行
41
68
  pty_read(id, { wait: true }) → 削減済みの出力を読む
42
69
  ```
43
70
 
71
+ ## デモ
72
+
73
+ <!-- demo gif: drop docs/demo.gif here (asciinema cast or animated GIF of the flow below) -->
74
+
75
+ 決め手の流れ: PTY を 1 個開き、その**中で** SSH にネストし、リモートでコマンドを実行し、**すでにトークン削減された**出力を読む — コマンドごとの接続し直しは無い。
76
+
77
+ ```text
78
+ # 1 — ローカル端末を 1 個握る(tmux 上・再起動を跨ぐ)
79
+ → pty_open()
80
+ ← { session_id: "t1", attach: "tmux -S /…/claude.sock attach -t t1" }
81
+
82
+ # 2 — その同じ端末の中で SSH にネスト(別ツールではない)
83
+ → pty_send("t1", "ssh 192.168.1.2")
84
+ ← sent
85
+ → pty_read("t1", { until: "\\$ $" }) # リモートのプロンプト = 「シェルに戻った」
86
+ ← user@remote:~$
87
+
88
+ # 3 — 同じ PTY のまま、リモートでコマンド実行(接続し直し無し)
89
+ → pty_send("t1", "uname -a")
90
+ → pty_read("t1", { until: "\\$ $" })
91
+ ← Linux remote 6.1.0 #1 SMP x86_64 GNU/Linux
92
+
93
+ # 4 — ノイズの多いコマンドを、コマンド別 reducer で読む
94
+ → pty_send("t1", "git status")
95
+ → pty_read("t1", { until: "\\$ $", rtk: true }) # 自前実装・rtk バイナリ不要
96
+ ← ## main…origin/main [ahead 1]
97
+ M src/core.ts
98
+ ?? notes.txt
99
+ [reduced: 制御文字除去 · 重複圧縮 · git-status reducer]
100
+ ```
101
+
102
+ この流れが「デモのための嘘」にならない理由:
103
+
104
+ - ステップ 2/3 が **`until`**(リモートのプロンプト)を使うのは、**ネスト中は quiescence が原理的に効かない**ため([完了検出](#完了検出4-層) / [既知の制約](#既知の制約バグではなく仕様))。ローカルシェルなら `{ wait: true }` だけで足りるが、ネスト中は `until`(または `mark: true`)が要る。
105
+ - 角括弧の `[reduced: …]` 行は `pty_read` が付けるメタ/復元ヒントの例示で、実際の文言は出力に応じて変わる。reducer は **自前実装**の `pty_read({ rtk: true })` 経路で、外部 `rtk` バイナリは不要。
106
+ - `t1` のソケットに人が `attach` すれば、同じ SSH セッションをライブで覗ける([人が覗く](#人が覗く))。
107
+
44
108
  ## 仕組み
45
109
 
46
110
  ```mermaid
@@ -138,6 +202,19 @@ npm link # ローカルで `aiterm-mcp` を PATH に
138
202
 
139
203
  ロジックは `src/core.ts`(tmux 制御・削減・完了検出・安全)と `src/rtk.ts`(コマンド別 reducer)、公開は `src/index.ts`。設計の出発点と reducer の移植元(pytest reducer は本家 rtk 0.42.0 と出力が byte 一致するよう移植・回帰テストで固定)は `prototype/python/` を参照。
140
204
 
205
+ ## 試す
206
+
207
+ 1 コマンド、clone もビルドも不要:
208
+
209
+ ```bash
210
+ claude mcp add --scope user --transport stdio aiterm -- npx -y aiterm-mcp
211
+ ```
212
+
213
+ aiterm がトークンの往復を 1 回でも省けたなら、**[リポジトリに star](https://github.com/kitepon-rgb/aiterm-mcp)** を — 他の人に見つけてもらう一番安い方法です。
214
+
215
+ - **npm:** https://www.npmjs.com/package/aiterm-mcp
216
+ - **Issue / バグ報告:** https://github.com/kitepon-rgb/aiterm-mcp/issues
217
+
141
218
  ## ライセンス
142
219
 
143
220
  MIT
package/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
  [![npm](https://img.shields.io/npm/v/aiterm-mcp.svg)](https://www.npmjs.com/package/aiterm-mcp)
9
9
  [![node](https://img.shields.io/node/v/aiterm-mcp)](https://nodejs.org)
10
10
  [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
11
+ [![npm downloads](https://img.shields.io/npm/dm/aiterm-mcp.svg)](https://www.npmjs.com/package/aiterm-mcp)
12
+ [![install size](https://packagephobia.com/badge?p=aiterm-mcp)](https://packagephobia.com/result?p=aiterm-mcp)
11
13
 
12
14
  > *(日本語: [README.ja.md](README.ja.md))*
13
15
 
@@ -15,6 +17,31 @@
15
17
 
16
18
  Just six tools — `pty_open` / `pty_send` / `pty_read` / `pty_key` / `pty_close` / `pty_list`. The backend is **tmux**, so sessions survive even if the MCP server or the AI client restarts.
17
19
 
20
+ ## Quickstart (≈60 seconds)
21
+
22
+ One command registers it in Claude Code — no clone, no build, `npx` fetches it each run:
23
+
24
+ ```bash
25
+ claude mcp add --scope user --transport stdio aiterm -- npx -y aiterm-mcp
26
+ ```
27
+
28
+ Restart Claude Code, then verify the connection:
29
+
30
+ ```bash
31
+ /mcp # aiterm should show as connected, exposing 6 tools
32
+ ```
33
+
34
+ Your first session — four calls, one persistent terminal:
35
+
36
+ ```text
37
+ pty_open() → { session_id: "t1", attach: "tmux -S … attach -t t1" }
38
+ pty_send("t1", "echo hello") → command sent into the PTY
39
+ pty_read("t1", { wait: true }) → "hello" (token-reduced, completion detected)
40
+ pty_close("t1") → terminal released
41
+ ```
42
+
43
+ That's it. The terminal in `t1` is real and persistent — `ssh`, `docker exec`, a REPL are just text you `pty_send` into it (see [Why](#why)). Prefer no install? Any MCP client can launch `npx -y aiterm-mcp` over stdio directly.
44
+
18
45
  ## Install
19
46
 
20
47
  It's on npm — no clone, no build:
@@ -41,6 +68,43 @@ pty_send(id, "uname -a") → run it on the remote
41
68
  pty_read(id, { wait: true }) → read the reduced output
42
69
  ```
43
70
 
71
+ ## Demo
72
+
73
+ <!-- demo gif: drop docs/demo.gif here (asciinema cast or animated GIF of the flow below) -->
74
+
75
+ The killer flow: open one PTY, nest into SSH *inside it*, run a command on the remote, and read back output that's already been token-reduced — no reconnect per command.
76
+
77
+ ```text
78
+ # 1 — grab one local terminal (lives in tmux; survives restarts)
79
+ → pty_open()
80
+ ← { session_id: "t1", attach: "tmux -S /…/claude.sock attach -t t1" }
81
+
82
+ # 2 — nest SSH *inside* that same terminal (not a separate tool)
83
+ → pty_send("t1", "ssh 192.168.1.2")
84
+ ← sent
85
+ → pty_read("t1", { until: "\\$ $" }) # remote prompt = "shell is back"
86
+ ← user@remote:~$
87
+
88
+ # 3 — run a command on the remote, over the SAME PTY (no reconnect)
89
+ → pty_send("t1", "uname -a")
90
+ → pty_read("t1", { until: "\\$ $" })
91
+ ← Linux remote 6.1.0 #1 SMP x86_64 GNU/Linux
92
+
93
+ # 4 — a noisy command, read with the per-command reducer
94
+ → pty_send("t1", "git status")
95
+ → pty_read("t1", { until: "\\$ $", rtk: true }) # self-contained, no rtk binary needed
96
+ ← ## main…origin/main [ahead 1]
97
+ M src/core.ts
98
+ ?? notes.txt
99
+ [reduced: control chars stripped · repeats collapsed · git-status reducer]
100
+ ```
101
+
102
+ Notes that make this accurate, not a demo lie:
103
+
104
+ - Step 2/3 use **`until`** with the remote prompt because **while nested, quiescence cannot fire by design** — see [Completion detection](#completion-detection-4-layers) and [Known constraints](#known-constraints-by-design-not-bugs). `{ wait: true }` alone works at the local shell; nested needs `until` (or `mark: true`).
105
+ - The bracketed `[reduced: …]` line is illustrative of the meta/restore hint `pty_read` appends; the exact text comes from your output. The reducer is the **self-contained** `pty_read({ rtk: true })` path — no external `rtk` binary required.
106
+ - A human can `attach` to the `t1` socket and watch the same SSH session live (see [A human can watch](#a-human-can-watch)).
107
+
44
108
  ## How it works
45
109
 
46
110
  ```mermaid
@@ -138,6 +202,19 @@ npm link # put `aiterm-mcp` on PATH locally
138
202
 
139
203
  Logic lives in `src/core.ts` (tmux control, reduction, completion detection, safety) and `src/rtk.ts` (per-command reducers); `src/index.ts` is the MCP surface. The design origin and the reducer's porting source (the pytest reducer is ported to be byte-exact with upstream rtk 0.42.0, locked by regression tests) are in `prototype/python/`.
140
204
 
205
+ ## Try it
206
+
207
+ One command, no clone, no build:
208
+
209
+ ```bash
210
+ claude mcp add --scope user --transport stdio aiterm -- npx -y aiterm-mcp
211
+ ```
212
+
213
+ If aiterm saved you a round-trip of tokens, **[star the repo](https://github.com/kitepon-rgb/aiterm-mcp)** — it's the cheapest way to help others find it.
214
+
215
+ - **npm:** https://www.npmjs.com/package/aiterm-mcp
216
+ - **Issues / bug reports:** https://github.com/kitepon-rgb/aiterm-mcp/issues
217
+
141
218
  ## License
142
219
 
143
220
  MIT
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
12
12
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
13
  import { z } from "zod";
14
14
  import * as core from "./core.js";
15
- const server = new McpServer({ name: "aiterm", version: "0.3.0" });
15
+ const server = new McpServer({ name: "aiterm", version: "0.3.1" });
16
16
  function ok(s) {
17
17
  return { content: [{ type: "text", text: s }] };
18
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiterm-mcp",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "AI-driven persistent terminal as a local stdio MCP server (tmux-backed). Holds one local PTY; SSH and containers are just commands you send into it. Token-reducing reads.",
5
5
  "keywords": [
6
6
  "mcp",