@vinkius-core/mcp-fusion-inspector 1.0.0

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.md ADDED
@@ -0,0 +1,218 @@
1
+ <p align="center">
2
+ <h1 align="center">@vinkius-core/mcp-fusion-inspector</h1>
3
+ <p align="center">
4
+ <strong>MCP Fusion Inspector</strong> — Real-time interactive terminal dashboard for MCP Fusion servers
5
+ </p>
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/@vinkius-core/mcp-fusion-inspector"><img src="https://img.shields.io/npm/v/@vinkius-core/mcp-fusion-inspector?color=blue" alt="npm" /></a>
10
+ <a href="https://github.com/vinkius-labs/mcp-fusion/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green" alt="License" /></a>
11
+ <img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen" alt="Node" />
12
+ </p>
13
+
14
+ ---
15
+
16
+ > Zero-overhead observability for MCP Fusion servers. Connects via **Shadow Socket** (IPC) — no stdio interference, no port conflicts, no agent disruption.
17
+
18
+ ## Why Inspector?
19
+
20
+ MCP servers communicate over stdio, which means traditional debugging tools (`console.log`, debuggers) are off-limits. The Inspector solves this by opening an **out-of-band Shadow Socket** (Named Pipe on Windows / Unix Domain Socket on Linux/macOS) that streams real-time telemetry without touching stdio.
21
+
22
+ ```
23
+ ┌─────────────────────────────────────────────┐
24
+ │ MCP Client (Claude, Cursor, etc.) │
25
+ │ ↕ stdio (MCP protocol) │
26
+ │ MCP Fusion Server │
27
+ │ ↕ Shadow Socket (IPC) │
28
+ │ Inspector TUI / stderr logger │
29
+ └─────────────────────────────────────────────┘
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```bash
35
+ # Launch interactive TUI (auto-discovers running server)
36
+ npx fusion inspect
37
+
38
+ # Short alias
39
+ npx fusion insp
40
+
41
+ # Built-in simulator (no server needed — great for demos)
42
+ npx fusion insp --demo
43
+
44
+ # Headless stderr output (ECS / K8s / CI)
45
+ npx fusion insp --out stderr
46
+
47
+ # Connect to a specific server PID
48
+ npx fusion insp --pid 12345
49
+ ```
50
+
51
+ ## Dashboard Panels
52
+
53
+ ### Topology
54
+
55
+ Live tool registry showing every registered tool and action with:
56
+
57
+ | Column | Description |
58
+ |--------|-------------|
59
+ | Status | `✓` ok, `✗` error, `⋯` pending |
60
+ | Tool | `group.action` qualified name |
61
+ | Type | `R/O` read-only, `W` write, `🔒` sandboxed, `◆FSM` state-gated |
62
+ | Latency | Last execution time in ms |
63
+ | Calls | Total invocation count |
64
+ | Middleware | Chain length per action |
65
+
66
+ Tabs: **Tools** · **Prompts** · **Resources**
67
+
68
+ ### Traffic Log
69
+
70
+ Real-time color-coded event stream — every pipeline stage appears as it happens:
71
+
72
+ ```
73
+ 19:32:01 ROUTE billing.createInvoice
74
+ 19:32:01 ZOD ✓ 2ms
75
+ 19:32:01 MW chain(2)
76
+ 19:32:01 EXEC ✓ 45ms
77
+ 19:32:01 SLICE 4.2KB → 1.1KB (73.8% saved)
78
+ 19:32:01 DLP ✖ $.user.email → [REDACTED]
79
+ ```
80
+
81
+ ### X-Ray Inspector
82
+
83
+ Select any tool in the list to see deep inspection in the right panel:
84
+
85
+ - **Error Autopsy** — Full exception with pipeline stage (`VALIDATE`, `MIDDLEWARE`, `EXECUTE`), self-healing recovery hints
86
+ - **Last Input** — Zod-validated arguments (pretty-printed JSON)
87
+ - **Select Reflection** — Which fields the AI chose via `_select` (e.g. "3 of 12 fields")
88
+ - **Late Guillotine** — Token economy: raw DB bytes vs. wire bytes with savings percentage bar
89
+ - **Cognitive Guardrails** — Array truncation from `agentLimit()` (e.g. "500 → 50 items")
90
+ - **DLP Redactions** — Masked PII paths (`$.user.email → [REDACTED]`)
91
+ - **Cognitive Rules** — System rules injected by the Presenter
92
+ - **Call History** — Rolling log with latency, status, and summary per call
93
+
94
+ ### Header Bar
95
+
96
+ Server name · PID · Heap usage · Uptime · Requests/second
97
+
98
+ ## Telemetry Events
99
+
100
+ The Inspector processes all events emitted by the MCP Fusion pipeline:
101
+
102
+ | Event | Source | Description |
103
+ |-------|--------|-------------|
104
+ | `topology` | `startServer()` | Tool registry snapshot (initial + hot-reload) |
105
+ | `heartbeat` | `startServer()` | PID, heap, uptime (every 5s) |
106
+ | `route` | Pipeline | Action routing resolution |
107
+ | `validate` | Pipeline | Zod validation result + duration |
108
+ | `middleware` | Pipeline | Middleware chain length |
109
+ | `execute` | Pipeline | Handler execution result + duration |
110
+ | `error` | Pipeline | Exception with recovery hints |
111
+ | `presenter.slice` | Presenter | Raw bytes vs. wire bytes (token savings) |
112
+ | `presenter.rules` | Presenter | Injected system rules |
113
+ | `dlp.redact` | DLP | PII redaction paths |
114
+ | `fsm.transition` | FSM Gate | State machine transition (from → to) |
115
+ | `sandbox.exec` | Sandbox | Sandboxed execution metrics |
116
+ | `governance` | Governance | Policy enforcement events |
117
+
118
+ ## Output Modes
119
+
120
+ ### Interactive TUI (default)
121
+
122
+ Full-screen terminal dashboard with keyboard navigation.
123
+
124
+ ```bash
125
+ fusion inspect
126
+ fusion insp --demo
127
+ ```
128
+
129
+ **Keyboard shortcuts:**
130
+
131
+ | Key | Action |
132
+ |-----|--------|
133
+ | `↑` `↓` / `j` `k` | Navigate tool list |
134
+ | `q` / `Ctrl+C` | Exit |
135
+
136
+ ### Headless (stderr)
137
+
138
+ Structured log output for non-TTY environments. Ideal for containers, CI/CD, and log aggregation.
139
+
140
+ ```bash
141
+ # Color-coded stderr
142
+ fusion insp --out stderr
143
+
144
+ # NDJSON format (set env var)
145
+ FUSION_LOG_FORMAT=json fusion insp --out stderr
146
+
147
+ # Pipe to file
148
+ fusion insp --out stderr | tee telemetry.log
149
+ ```
150
+
151
+ Respects `NO_COLOR` environment variable.
152
+
153
+ ## Programmatic API
154
+
155
+ ```typescript
156
+ import {
157
+ commandTop,
158
+ streamToStderr,
159
+ startSimulator,
160
+ } from '@vinkius-core/mcp-fusion-inspector';
161
+
162
+ // Launch the interactive TUI
163
+ await commandTop({ pid: 12345 });
164
+
165
+ // Launch the headless stderr logger
166
+ await streamToStderr({ pid: 12345 });
167
+
168
+ // Start the built-in simulator (returns a TelemetryBus)
169
+ const bus = await startSimulator({ rps: 5 });
170
+ // ... use bus.path to connect TUI or logger
171
+ await bus.close();
172
+ ```
173
+
174
+ ### Rendering Utilities
175
+
176
+ Low-level ANSI primitives exported for custom TUI implementations:
177
+
178
+ ```typescript
179
+ import {
180
+ ansi,
181
+ ScreenManager,
182
+ box,
183
+ hline,
184
+ pad,
185
+ truncate,
186
+ progressBar,
187
+ stringWidth,
188
+ RingBuffer,
189
+ } from '@vinkius-core/mcp-fusion-inspector';
190
+ ```
191
+
192
+ ## Installation
193
+
194
+ ```bash
195
+ npm install @vinkius-core/mcp-fusion-inspector
196
+ ```
197
+
198
+ ### Peer Dependency
199
+
200
+ Requires `@vinkius-core/mcp-fusion` ≥ 3.0.0 (provides `TelemetryEvent` types and `TelemetryBus`).
201
+
202
+ ## How It Works
203
+
204
+ 1. **Server side** — `startServer({ telemetry: true })` creates a Shadow Socket (Named Pipe / UDS) and streams `TelemetryEvent` objects as newline-delimited JSON.
205
+
206
+ 2. **Client side** — The Inspector connects to the Shadow Socket, parses events, and updates the TUI state at 15 fps (throttled to prevent flicker).
207
+
208
+ 3. **Auto-discovery** — When no `--pid` or `--path` is specified, the Inspector scans for the well-known IPC path pattern and auto-connects. If no server is found, it polls every 2 seconds. If the connection drops, it auto-reconnects.
209
+
210
+ ## Requirements
211
+
212
+ - **Node.js** ≥ 18.0.0
213
+ - **Interactive terminal** (for TUI mode) — `--out stderr` for non-TTY environments
214
+ - **MCP Fusion** ≥ 3.0.0 (peer dependency)
215
+
216
+ ## License
217
+
218
+ [Apache-2.0](https://github.com/vinkius-labs/mcp-fusion/blob/main/LICENSE)
@@ -0,0 +1,160 @@
1
+ /**
2
+ * AnsiRenderer — Low-Level Terminal Rendering Engine
3
+ *
4
+ * Pure ANSI escape sequence renderer for the Inspector TUI.
5
+ * Zero dependencies — uses only built-in Node.js `process.stdout`.
6
+ *
7
+ * Features:
8
+ * - Alternate screen buffer management (like vim/htop)
9
+ * - Double-buffered rendering (only emit changed cells)
10
+ * - Unicode-aware column width calculation (Gotcha #3: emoji double-width)
11
+ * - Debounced resize handling (Gotcha #4: SIGWINCH bomb)
12
+ * - Box drawing with Unicode characters
13
+ *
14
+ * @module
15
+ */
16
+ export declare const ansi: {
17
+ readonly cyan: (s: string) => string;
18
+ readonly green: (s: string) => string;
19
+ readonly red: (s: string) => string;
20
+ readonly yellow: (s: string) => string;
21
+ readonly magenta: (s: string) => string;
22
+ readonly blue: (s: string) => string;
23
+ readonly dim: (s: string) => string;
24
+ readonly bold: (s: string) => string;
25
+ readonly inverse: (s: string) => string;
26
+ readonly reset: "\u001B[0m";
27
+ readonly fg: {
28
+ readonly cyan: "\u001B[36m";
29
+ readonly green: "\u001B[32m";
30
+ readonly red: "\u001B[31m";
31
+ readonly yellow: "\u001B[33m";
32
+ readonly magenta: "\u001B[35m";
33
+ readonly blue: "\u001B[34m";
34
+ readonly white: "\u001B[37m";
35
+ };
36
+ readonly bg: {
37
+ readonly red: "\u001B[41m";
38
+ readonly green: "\u001B[42m";
39
+ readonly yellow: "\u001B[43m";
40
+ readonly blue: "\u001B[44m";
41
+ };
42
+ readonly hideCursor: "\u001B[?25l";
43
+ readonly showCursor: "\u001B[?25h";
44
+ readonly altScreen: "\u001B[?1049h";
45
+ readonly mainScreen: "\u001B[?1049l";
46
+ readonly clearScreen: "\u001B[2J\u001B[H";
47
+ readonly moveTo: (row: number, col: number) => string;
48
+ readonly clearLine: "\u001B[2K";
49
+ };
50
+ /**
51
+ * Calculate the visual width of a string in terminal columns.
52
+ *
53
+ * Handles:
54
+ * - East Asian Fullwidth characters (2 columns)
55
+ * - Emoji (2 columns each)
56
+ * - Combining characters (0 columns)
57
+ * - ANSI escape sequences (0 columns — invisible)
58
+ * - Variation selectors and ZWJ (0 columns)
59
+ *
60
+ * This is a lightweight approximation inspired by `string-width`.
61
+ * It avoids the full ICU dependency by checking Unicode block ranges.
62
+ *
63
+ * @param str - The string to measure
64
+ * @returns Width in terminal columns
65
+ */
66
+ export declare function stringWidth(str: string): number;
67
+ /**
68
+ * Truncate a string to fit within a maximum visual column width.
69
+ * ANSI codes are preserved correctly.
70
+ *
71
+ * @param str - String to truncate
72
+ * @param maxWidth - Maximum visual width in columns
73
+ * @param suffix - Suffix to add if truncated (default: '…')
74
+ * @returns Truncated string
75
+ */
76
+ export declare function truncate(str: string, maxWidth: number, suffix?: string): string;
77
+ /**
78
+ * Pad a string to a specific visual width with spaces.
79
+ *
80
+ * @param str - String to pad
81
+ * @param targetWidth - Desired visual width
82
+ * @param align - 'left' or 'right' alignment
83
+ * @returns Padded string
84
+ */
85
+ export declare function pad(str: string, targetWidth: number, align?: 'left' | 'right'): string;
86
+ /** Unicode box drawing characters */
87
+ export declare const box: {
88
+ readonly topLeft: "╭";
89
+ readonly topRight: "╮";
90
+ readonly bottomLeft: "╰";
91
+ readonly bottomRight: "╯";
92
+ readonly horizontal: "─";
93
+ readonly vertical: "│";
94
+ readonly teeRight: "├";
95
+ readonly teeLeft: "┤";
96
+ readonly teeDown: "┬";
97
+ readonly teeUp: "┴";
98
+ readonly cross: "┼";
99
+ };
100
+ /**
101
+ * Draw a horizontal line with box-drawing characters.
102
+ * @param width - Total width including corners/tees
103
+ * @param left - Left character (e.g. '├' or '╭')
104
+ * @param right - Right character (e.g. '┤' or '╮')
105
+ * @param fill - Fill character (default: '─')
106
+ */
107
+ export declare function hline(width: number, left: string, right: string, fill?: "─"): string;
108
+ /**
109
+ * Render an ASCII progress/savings bar.
110
+ *
111
+ * @param ratio - Value between 0 and 1
112
+ * @param width - Total width in columns
113
+ * @param filledChar - Character for filled portion (default: '█')
114
+ * @param emptyChar - Character for empty portion (default: '░')
115
+ * @returns Colored progress bar string
116
+ */
117
+ export declare function progressBar(ratio: number, width: number, filledChar?: string, emptyChar?: string): string;
118
+ /**
119
+ * Low-level screen manager for alternate buffer TUI rendering.
120
+ *
121
+ * Provides:
122
+ * - Enter/exit alternate screen buffer
123
+ * - Raw mode stdin management
124
+ * - Debounced resize handling (Gotcha #4)
125
+ * - Direct cursor positioning writes
126
+ */
127
+ export declare class ScreenManager {
128
+ private _active;
129
+ private _resizeTimer;
130
+ private _resizeCallback;
131
+ private _inputCallback;
132
+ private _cols;
133
+ private _rows;
134
+ /** Current terminal columns */
135
+ get cols(): number;
136
+ /** Current terminal rows */
137
+ get rows(): number;
138
+ /** Whether the screen is active (alternate buffer + raw mode) */
139
+ get active(): boolean;
140
+ /**
141
+ * Enter the alternate screen buffer and enable raw mode.
142
+ *
143
+ * @param onResize - Callback for terminal resize (debounced 100ms, Gotcha #4)
144
+ * @param onInput - Callback for keyboard input (raw bytes)
145
+ */
146
+ enter(onResize: () => void, onInput: (key: string, raw: Buffer) => void): void;
147
+ /**
148
+ * Exit the alternate screen buffer and restore normal operation.
149
+ */
150
+ exit(): void;
151
+ /** Write at a specific position (1-indexed) */
152
+ writeAt(row: number, col: number, text: string): void;
153
+ /** Clear the entire screen */
154
+ clear(): void;
155
+ /** Flush output */
156
+ flush(): void;
157
+ private _handleResize;
158
+ private _handleInput;
159
+ }
160
+ //# sourceMappingURL=AnsiRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnsiRenderer.d.ts","sourceRoot":"","sources":["../src/AnsiRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,eAAO,MAAM,IAAI;uBAEA,MAAM,KAAG,MAAM;wBACf,MAAM,KAAG,MAAM;sBACf,MAAM,KAAG,MAAM;yBACf,MAAM,KAAG,MAAM;0BACf,MAAM,KAAG,MAAM;uBACf,MAAM,KAAG,MAAM;sBACf,MAAM,KAAG,MAAM;uBACf,MAAM,KAAG,MAAM;0BACf,MAAM,KAAG,MAAM;;;;;;;;;;;;;;;;;;;;;;2BAoBd,MAAM,OAAO,MAAM,KAAG,MAAM;;CAEpC,CAAC;AAMX;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqD/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,MAAM,CAiC5E;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,OAAgB,GAAG,MAAM,CAK9F;AAMD,qCAAqC;AACrC,eAAO,MAAM,GAAG;;;;;;;;;;;;CAON,CAAC;AAEX;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,MAAiB,GAAG,MAAM,CAE/F;AAMD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,SAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAYnG;AAMD;;;;;;;;GAQG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAA4C;IAChE,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,cAAc,CAAmD;IACzE,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,KAAK,CAAM;IAEnB,+BAA+B;IAC/B,IAAI,IAAI,IAAI,MAAM,CAAuB;IACzC,4BAA4B;IAC5B,IAAI,IAAI,IAAI,MAAM,CAAuB;IACzC,iEAAiE;IACjE,IAAI,MAAM,IAAI,OAAO,CAAyB;IAE9C;;;;;OAKG;IACH,KAAK,CACD,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5C,IAAI;IAwBP;;OAEG;IACH,IAAI,IAAI,IAAI;IAwBZ,+CAA+C;IAC/C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIrD,8BAA8B;IAC9B,KAAK,IAAI,IAAI;IAIb,mBAAmB;IACnB,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,aAAa,CAYnB;IAEF,OAAO,CAAC,YAAY,CAGlB;CACL"}