# 機能設計書 99-Model Context Protocol

## 概要

本ドキュメントはNushellのModel Context Protocol（MCP）サーバー実装（nu-mcp）について記述する。AIモデルとNushellの統合を可能にするMCPサーバーの設計を定義する。

### 本機能の処理概要

nu-mcpは、Model Context Protocol（MCP）に準拠したサーバーとして、AIモデル（LLM）からNushellコマンドを実行できるようにする。AIアシスタントがシェルコマンドを実行し、システムと対話するためのブリッジとして機能する。

**業務上の目的・背景**：AIアシスタントがユーザーのタスクを支援する際、シェルコマンドの実行が必要となることが多い。MCPサーバーは、AIモデルが安全かつ構造化された方法でNushellと対話できるインターフェースを提供する。

**機能の利用シーン**：
- AIアシスタントによるファイル操作やシステム管理
- LLMを活用した自動化スクリプト
- インタラクティブなAI駆動のシェルセッション
- AIによるデータ処理とパイプライン構築

**主要な処理内容**：
1. MCP通信プロトコルの処理（stdio/HTTP）
2. Nushellコード評価
3. コマンドリストと ヘルプの提供
4. 実行履歴の管理
5. キャンセル対応

**関連システム・外部連携**：rmcpクレート（MCP実装）、hyper（HTTP）、tokio（非同期ランタイム）

**権限による制御**：MCPサーバーとして起動時にengine_state.is_mcpをtrueに設定。外部コマンドのstdin継承を無効化。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はサーバーとして動作し、特定の画面とは関連しない |

## 機能種別

プロトコルサーバー / AI統合 / コマンド評価

## 入力仕様

### 入力パラメータ

#### MCPトランスポート設定

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| transport | McpTransport | Yes | Stdio または Http { port } | - |

#### ツール: list_commands

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| find | String | No | コマンド名・説明・検索タームで検索 | - |

#### ツール: command_help

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | コマンド名 | 有効なコマンド名 |

#### ツール: evaluate

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String | Yes | 評価するNushellソースコード | - |

### 入力データソース

- MCPクライアント（AIモデル）からのJSON-RPCリクエスト
- stdio または HTTP/SSE経由

## 出力仕様

### 出力データ

#### evaluate レスポンス

| 項目名 | 型 | 説明 |
|--------|-----|------|
| cwd | String | 現在の作業ディレクトリ |
| history_index | Int | 履歴インデックス |
| timestamp | Date | 実行タイムスタンプ |
| output | String | 実行結果（NUON形式） |
| note | String | 出力が切り詰められた場合の注記 |

#### エラーレスポンス

| 項目名 | 型 | 説明 |
|--------|-----|------|
| code | String | エラーコード |
| msg | String | エラーメッセージ |
| severity | String | エラー重大度 |
| help | String | ヘルプ情報 |
| labels | List | ソース位置情報 |

### 出力先

- MCPクライアントへのJSON-RPCレスポンス

## 処理フロー

### 処理シーケンス

```
MCPサーバー起動:
1. トランスポート選択
   ├─ Stdio: stdin/stdout通信
   └─ Http: HTTP/SSE通信
2. EngineStateの初期化
3. NushellMcpServerの生成
4. ツールルーターの設定
5. サーバーループ開始

evaluate実行:
1. 状態のフォーク（キャンセル対応）
2. ソースコードのパース
3. エラーチェック（parse/compile）
4. ブロック評価
5. パイプライン出力処理
6. 履歴への追加
7. レスポンス生成（NUON形式）
8. 状態のマージまたは破棄
```

### フローチャート

```mermaid
flowchart TD
    A[MCPサーバー起動] --> B{トランスポート}
    B -->|Stdio| C[run_stdio_server]
    B -->|Http| D[run_http_server]
    C --> E[NushellMcpServer::serve]
    D --> F[StreamableHttpService]
    F --> E
    E --> G[ツールリクエスト待機]
    G --> H{ツール種別}
    H -->|list_commands| I[help commands実行]
    H -->|command_help| J[help <name>実行]
    H -->|evaluate| K[eval_async]
    K --> L[状態フォーク]
    L --> M[nu_parser::parse]
    M --> N{エラー?}
    N -->|Yes| O[user_input_error]
    N -->|No| P[eval_block]
    P --> Q[process_pipeline]
    Q --> R[履歴追加]
    R --> S[状態マージ]
    S --> T[NUONレスポンス]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-01 | ANSI無効化 | MCP出力ではANSIカラーコードを無効化 | 常時 |
| BR-99-02 | 状態永続化 | 変数・環境変数は評価間で永続 | REPL風動作 |
| BR-99-03 | 履歴管理 | $historyでアクセス可能、リングバッファ | 常時 |
| BR-99-04 | 出力制限 | デフォルト10KB、NU_MCP_OUTPUT_LIMITで設定可能 | 常時 |
| BR-99-05 | キャンセル対応 | キャンセル時は状態変更を破棄 | キャンセル時 |
| BR-99-06 | TTY切り離し | setsid()でターミナル切り離し（Unix） | 起動時 |

### 計算ロジック

**履歴管理**:
- デフォルト100エントリ（NU_MCP_HISTORY_LIMITで設定可能）
- リングバッファとして古いエントリを削除
- $history.0, $history.1等でアクセス

**出力制限**:
- デフォルト10KB（DEFAULT_OUTPUT_LIMIT）
- 超過時はnoteフィールドで通知
- 完全な出力は$historyで取得可能

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| -32602 | Invalid params | パース/コンパイルエラー | 入力コードを修正 |
| -32603 | Internal error | ランタイムエラー | エラー内容を確認 |
| - | Cancelled | 操作がキャンセルされた | 再実行 |

### リトライ仕様

- キャンセル後は状態が維持されるため安全に再実行可能

## トランザクション仕様

- 評価は状態のフォーク上で実行
- 成功時のみメイン状態にマージ
- キャンセル/エラー時はフォーク状態を破棄

## パフォーマンス要件

- HTTP: セッションキープアライブ30分
- SSEキープアライブ: 15秒間隔
- チャネル容量: 16メッセージ
- 非同期評価でブロッキング回避

## セキュリティ考慮事項

- setsid()でターミナル切り離し
- 外部コマンドのstdin継承無効化
- パスワードプロンプト等による無限待機を防止
- is_mcpフラグで非対話モード強制

## 備考

- MCPはAnthropicが策定したAI-システム間通信プロトコル
- rmcpクレートはMCPのRust実装
- NUON形式は機械可読なNushellデータ形式

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: サーバー構造を理解する

NushellMcpServerの構造と初期化を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | server.rs | `crates/nu-mcp/src/server.rs` | NushellMcpServer構造体（16-19行目） |
| 1-2 | server.rs | `crates/nu-mcp/src/server.rs` | new()での初期化（23-33行目） |

**読解のコツ**: NushellMcpServerはtool_router（ツールディスパッチ）とevaluator（評価器）を持つ。newでANSIカラーを無効化している点に注目。

#### Step 2: ツール定義を理解する

MCPツールの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | server.rs | `crates/nu-mcp/src/server.rs` | list_commands（35-49行目） |
| 2-2 | server.rs | `crates/nu-mcp/src/server.rs` | command_help（51-61行目） |
| 2-3 | server.rs | `crates/nu-mcp/src/server.rs` | evaluate（63-71行目） |

**主要処理フロー（server.rs）**:
1. **#[tool]マクロ**: ツールをMCPに登録
2. **list_commands**: `help commands`を実行
3. **command_help**: `help <name>`を実行
4. **evaluate**: eval_asyncでコード評価

#### Step 3: 評価器を理解する

Evaluatorの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | evaluation.rs | `crates/nu-mcp/src/evaluation.rs` | Evaluator構造体（208-210行目） |
| 3-2 | evaluation.rs | `crates/nu-mcp/src/evaluation.rs` | eval_async（280-333行目） |
| 3-3 | evaluation.rs | `crates/nu-mcp/src/evaluation.rs` | eval_on_state（365-445行目） |

**主要処理フロー（evaluation.rs）**:
1. **286-289行目**: 状態のフォーク
2. **294行目**: ブロッキングタスクで評価
3. **302-308行目**: キャンセル監視タスク
4. **311-332行目**: 結果処理と状態マージ

#### Step 4: トランスポートを理解する

サーバー起動とトランスポート処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | lib.rs | `crates/nu-mcp/src/lib.rs` | McpTransport列挙型（32-42行目） |
| 4-2 | lib.rs | `crates/nu-mcp/src/lib.rs` | initialize_mcp_server（44-91行目） |
| 4-3 | lib.rs | `crates/nu-mcp/src/lib.rs` | run_http_server（117-172行目） |

### プログラム呼び出し階層図

```
initialize_mcp_server()
    │
    ├─ setsid()（Unix）
    │      └─ ターミナル切り離し
    │
    ├─ engine_state.is_mcp = true
    │
    └─ Runtime::block_on()
           │
           ├─ run_stdio_server()
           │      └─ NushellMcpServer::new().serve(stdio())
           │
           └─ run_http_server()
                  └─ StreamableHttpService
                         └─ NushellMcpServer::new()

NushellMcpServer
    │
    ├─ list_commands()
    │      └─ evaluator.eval_async("help commands")
    │
    ├─ command_help()
    │      └─ evaluator.eval_async("help <name>")
    │
    └─ evaluate()
           └─ evaluator.eval_async(input)
                  │
                  ├─ state.fork()
                  │      └─ 状態のコピー + Signals設定
                  │
                  ├─ spawn_blocking(eval_inner)
                  │      ├─ nu_parser::parse()
                  │      ├─ engine_state.merge_delta()
                  │      ├─ eval_block()
                  │      └─ process_pipeline()
                  │
                  └─ 状態マージまたは破棄
```

### データフロー図

```
[入力]                    [処理]                         [出力]

MCPリクエスト ─────────▶  NushellMcpServer    ─────────▶  MCPレスポンス
(JSON-RPC)                │
                          ├─ list_commands
                          │      └─ "help commands"
                          │
                          ├─ command_help
                          │      └─ "help <name>"
                          │
                          └─ evaluate
                                 │
                                 ▼
                          Evaluator.eval_async()
                                 │
                                 ├─ fork state
                                 │
                                 ├─ parse → Block
                                 │
                                 ├─ eval_block → PipelineData
                                 │
                                 ├─ process_pipeline → Value
                                 │
                                 ├─ history.push()
                                 │
                                 └─ to_nuon()
                                        │
                                        ▼
                                 {cwd, history_index,
                                  timestamp, output}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lib.rs | `crates/nu-mcp/src/lib.rs` | ソース | MCPサーバー初期化、トランスポート |
| server.rs | `crates/nu-mcp/src/server.rs` | ソース | NushellMcpServer、ツール定義 |
| evaluation.rs | `crates/nu-mcp/src/evaluation.rs` | ソース | Evaluator、コード評価 |
| history.rs | `crates/nu-mcp/src/history.rs` | ソース | 実行履歴管理 |
| instructions.md | `crates/nu-mcp/src/instructions.md` | ドキュメント | AIへの指示文 |
| evaluate_tool.md | `crates/nu-mcp/src/evaluate_tool.md` | ドキュメント | evaluateツールの説明 |
