cursor-mcp-feedback 2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 yuanmingchen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,263 @@
1
+ # MCP Feedback App
2
+
3
+ Interactive feedback UI that renders directly inside MCP hosts (Claude, Cursor, etc.) using the [MCP Apps](https://modelcontextprotocol.io/extensions/apps/overview) extension. Includes a **macOS floating companion app** for bidirectional feedback and pending message management.
4
+
5
+ When an AI agent calls the `interactive_feedback` tool, a feedback panel appears inline in the conversation — and optionally in the floating app. The user can respond from either side.
6
+
7
+ ## Features
8
+
9
+ ### MCP App Panel (in-conversation UI)
10
+
11
+ - **Inline feedback UI** — summary with Markdown rendering + input area, directly in the conversation
12
+ - **Dark mode** — auto-detects host theme (transparent background adapts to light/dark)
13
+ - **Image support** — paste (Cmd+V), drag & drop, file picker with preview
14
+ - **Quick replies** — Continue, LGTM, Fix, Pause one-click buttons
15
+ - **Auto-append** — automatically appends a configurable reminder to every feedback
16
+ - **Keyboard shortcut** — Ctrl/Cmd+Enter to submit feedback
17
+ - **Blocking tool pattern** — `interactive_feedback` blocks until user submits via the UI
18
+
19
+ ### Floating Companion App (macOS)
20
+
21
+ - **Bidirectional feedback** — both the MCP App panel and floating app receive AI summaries; respond from either side
22
+ - **Pending messages** — queue messages that redirect the agent mid-task (delivered via `preToolUse` hook)
23
+ - **Per-session tabs** — manage multiple agent sessions with project directory info
24
+ - **Chat history** — full conversation history loaded from `events.jsonl` per session
25
+ - **Image support** — paste images (Cmd+V), file picker, thumbnails in chat, click to preview
26
+ - **Global hotkey** — Cmd+Shift+M to toggle the panel
27
+ - **Floating button** — collapsible/expandable, draggable, always-on-top
28
+ - **State persistence** — window position, size, expanded state, input draft all persist across restarts
29
+ - **Enter to send** — Enter sends, Shift+Enter for newline, IME-safe
30
+ - **Menu bar icon** — quick access via status bar
31
+
32
+ ### Cursor Integration
33
+
34
+ - **Auto-install** — MCP server config, Cursor rules, and hooks are all auto-configured on first startup
35
+ - **Subagent protection** — hooks prevent subagents from calling `interactive_feedback`
36
+ - **Session lifecycle** — automatic session tracking via hooks (`sessionStart`, `preToolUse`, etc.)
37
+ - **Event logging** — all interactions logged to `events.jsonl` per session for chat history
38
+
39
+ ## Architecture
40
+
41
+ ```
42
+ ┌─────────────────────────────────────────────────┐
43
+ │ MCP Host (Cursor / Claude) │
44
+ │ ┌──────────┐ ┌────────────────────┐ │
45
+ │ │ AI Agent │ │ MCP App Panel │ │
46
+ │ │ │ │ (sandboxed iframe) │ │
47
+ │ │ calls │ │ sessionId embedded │ │
48
+ │ │ tool ────┼────┼─► renders inline │ │
49
+ │ └──────────┘ └────────┬───────────┘ │
50
+ └────────────────────────────┼────────────────────┘
51
+ │ callServerTool
52
+
53
+ ┌───────────────────────────┐
54
+ │ MCP Server │
55
+ │ interactive_feedback │ ← polls session file
56
+ │ submit_feedback │ ← writes resolved file
57
+ │ get_system_info │
58
+ └───────────┬───────────────┘
59
+
60
+ ┌───────────▼───────────────┐
61
+ │ ~/.cursor-mcp-feedback/ │
62
+ │ sessions/{uuid}.json │ ← bidirectional channel
63
+ │ sessions/{convId}/ │
64
+ │ events.jsonl │ ← chat history
65
+ │ pending.json │ ← queued messages
66
+ │ meta.json │ ← session metadata
67
+ │ active-sessions.json │
68
+ └───────────┬───────────────┘
69
+ │ file watch
70
+ ┌───────────▼───────────────┐
71
+ │ Floating App (macOS) │
72
+ │ SwiftUI + AppKit │
73
+ │ - bidirectional feedback │
74
+ │ - pending messages │
75
+ │ - per-session chat UI │
76
+ └───────────────────────────┘
77
+ ```
78
+
79
+ ## Installation
80
+
81
+ ### Quick Install (npm)
82
+
83
+ ```bash
84
+ npm install -g cursor-mcp-feedback
85
+ ```
86
+
87
+ On install, `postinstall` automatically configures Cursor (mcp.json, rules, hooks). Just restart Cursor and the MCP server is ready.
88
+
89
+ ### From Source
90
+
91
+ ```bash
92
+ git clone git@repo.advai.net:cash/incubating/cusor-feedback-v2.git cursor-mcp-feedback
93
+ cd cursor-mcp-feedback
94
+ npm install
95
+ npm run build
96
+ ```
97
+
98
+ ### Floating Companion App (macOS)
99
+
100
+ ```bash
101
+ cd floating-app
102
+ swift build -c release
103
+ # Binary: .build/release/MCPPending
104
+ ```
105
+
106
+ To auto-launch on login, add `.build/release/MCPPending` to System Settings > General > Login Items, or run manually.
107
+
108
+ ### CLI: Queue Pending Messages
109
+
110
+ ```bash
111
+ # List active sessions
112
+ cursor-mcp-feedback queue sessions
113
+
114
+ # Queue a message to the most recent session
115
+ cursor-mcp-feedback queue "please focus on the API layer"
116
+
117
+ # Queue to a specific session
118
+ cursor-mcp-feedback queue "fix the bug" --session <session-id>
119
+
120
+ # List pending messages
121
+ cursor-mcp-feedback queue list
122
+
123
+ # Clear pending messages
124
+ cursor-mcp-feedback queue clear
125
+ ```
126
+
127
+ ### Configure your MCP host
128
+
129
+ #### Cursor (auto-configured)
130
+
131
+ On first startup (or `npm install -g`), the MCP server **automatically configures** itself in `~/.cursor/mcp.json` with the correct absolute paths. It also auto-installs:
132
+
133
+ - **Cursor rule** (`~/.cursor/rules/cursor-mcp-feedback.mdc`) — instructs the agent to call `interactive_feedback`
134
+ - **Cursor hooks** (`~/.cursor/hooks/`) — subagent protection + pending message delivery + event logging
135
+ - **hooks.json entries** — registers `sessionStart`, `subagentStart`, `subagentStop`, `beforeMCPExecution`, `preToolUse`, `afterMCPExecution` hooks
136
+
137
+ All auto-installed files are kept in sync on every startup (hash-based diffing, idempotent).
138
+
139
+ To manually configure instead, add to `~/.cursor/mcp.json`:
140
+
141
+ ```json
142
+ {
143
+ "mcpServers": {
144
+ "cursor-mcp-feedback": {
145
+ "command": "node",
146
+ "args": ["/absolute/path/to/cursor-mcp-feedback/dist/main.js"],
147
+ "timeout": 86400,
148
+ "env": {
149
+ "MCP_FEEDBACK_TIMEOUT": "86400"
150
+ }
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ #### Claude Desktop
157
+
158
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
159
+
160
+ ```json
161
+ {
162
+ "mcpServers": {
163
+ "cursor-mcp-feedback": {
164
+ "command": "node",
165
+ "args": ["/absolute/path/to/cursor-mcp-feedback/dist/main.js"],
166
+ "timeout": 86400,
167
+ "env": {
168
+ "MCP_FEEDBACK_TIMEOUT": "86400"
169
+ }
170
+ }
171
+ }
172
+ }
173
+ ```
174
+
175
+ ## Cursor Hooks
176
+
177
+ | Hook | Event | Purpose |
178
+ |------|-------|---------|
179
+ | `block-cursor-mcp-feedback.js` | `subagentStart` | Record subagent_id to negative list |
180
+ | `block-cursor-mcp-feedback.js` | `subagentStop` | Remove subagent_id on completion |
181
+ | `block-cursor-mcp-feedback.js` | `beforeMCPExecution` | Deny cursor-mcp-feedback calls from subagents |
182
+ | `block-cursor-mcp-feedback.js` | `afterMCPExecution` | Log feedback_request/response events to events.jsonl |
183
+ | `consume-pending.js` | `preToolUse` | Consume pending messages and inject as agent feedback |
184
+
185
+ ## Keyboard Shortcuts
186
+
187
+ | Shortcut | Context | Action |
188
+ |----------|---------|--------|
189
+ | `⌘+Enter` / `Ctrl+Enter` | MCP App Panel | Submit feedback |
190
+ | `Enter` | Floating App | Send message / feedback |
191
+ | `Shift+Enter` | Floating App | Insert newline |
192
+ | `⌘+Shift+M` | Global | Toggle floating panel |
193
+ | `Esc` | Floating App | Collapse to floating button |
194
+ | `⌘+V` | Floating App | Paste image from clipboard |
195
+
196
+ ## UI Settings
197
+
198
+ | Setting | Default | Persistence | Description |
199
+ |---------|---------|-------------|-------------|
200
+ | Auto-append reminder | On | `~/.cursor-mcp-feedback-settings.json` | Appends text to every feedback |
201
+ | Auto-append text | `After completing, call interactive_feedback...` | Server-side | The text appended after each feedback |
202
+
203
+ ## Server Configuration
204
+
205
+ | Environment Variable | Default | Description |
206
+ |---------------------|---------|-------------|
207
+ | `MCP_FEEDBACK_TIMEOUT` | `86400` (24h) | Server-side timeout in seconds |
208
+
209
+ ## Development
210
+
211
+ ```bash
212
+ npm run build:ui # Build the UI (Vite → single-file HTML)
213
+ npm run build:server # Compile TypeScript server
214
+ npm run build # Both
215
+ npm run dev # Run with tsx (dev mode, stdio)
216
+ ```
217
+
218
+ ### Project Structure
219
+
220
+ ```
221
+ src/
222
+ App.tsx # Main React component (MCP App Panel UI)
223
+ mcp-app.tsx # React entry point
224
+ styles/app.css # Styles (light + dark theme)
225
+ server.ts # MCP server (tools + resources)
226
+ main.ts # Entry point (stdio/HTTP + auto-install)
227
+ session-store.ts # File-based session CRUD
228
+ logger.ts # File logging
229
+ hooks/
230
+ block-cursor-mcp-feedback.js # Subagent protection + event logging
231
+ consume-pending.js # Pending message delivery
232
+ session-utils.js # Shared session utilities
233
+ floating-app/
234
+ Sources/
235
+ FloatingApp.swift # App delegate, menu bar, window management
236
+ FloatingPanel.swift # NSPanel subclass (keyboard, IME handling)
237
+ FloatingButtonView.swift # Collapsed floating button
238
+ PendingPanelView.swift # Main panel UI (chat, input, tabs)
239
+ SessionManager.swift # Session data, chat history, file I/O
240
+ FileWatcher.swift # File system event monitoring
241
+ ImagePreviewWindow.swift # Image preview via system Preview.app
242
+ Package.swift # Swift Package Manager config
243
+ rules/
244
+ cursor-mcp-feedback.mdc # Cursor rule (auto-installed)
245
+ ```
246
+
247
+ ## MCP Tools
248
+
249
+ | Tool | Visibility | Description |
250
+ |------|-----------|-------------|
251
+ | `interactive_feedback` | model | Presents summary (Markdown), blocks until user responds |
252
+ | `submit_feedback` | app-only | Submits user feedback with optional images (called from UI) |
253
+ | `get_system_info` | model | Returns OS, architecture, Node.js version |
254
+
255
+ ## Prerequisites
256
+
257
+ - Node.js >= 18
258
+ - macOS 13+ (for floating companion app)
259
+ - MCP host with [MCP Apps](https://modelcontextprotocol.io/extensions/client-matrix) support
260
+
261
+ ## License
262
+
263
+ MIT
@@ -0,0 +1,3 @@
1
+ export declare function log(msg: string): void;
2
+ export declare function logError(msg: string): void;
3
+ export declare function logObj(msg: string, obj: Record<string, unknown>): void;
package/dist/logger.js ADDED
@@ -0,0 +1,25 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import * as os from "node:os";
4
+ const LOG_FILE = path.join(os.homedir(), ".cursor-mcp-feedback.log");
5
+ const PID = process.pid;
6
+ function formatLine(level, msg) {
7
+ const ts = new Date().toISOString();
8
+ return `[${ts}] [pid=${PID}] [${level}] ${msg}\n`;
9
+ }
10
+ export function log(msg) {
11
+ const line = formatLine("INFO", msg);
12
+ fs.appendFileSync(LOG_FILE, line);
13
+ console.error("[mcp-feedback]", msg);
14
+ }
15
+ export function logError(msg) {
16
+ const line = formatLine("ERROR", msg);
17
+ fs.appendFileSync(LOG_FILE, line);
18
+ console.error("[mcp-feedback] ERROR:", msg);
19
+ }
20
+ export function logObj(msg, obj) {
21
+ const extra = Object.entries(obj)
22
+ .map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`)
23
+ .join(" ");
24
+ log(`${msg} (${extra})`);
25
+ }
package/dist/main.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Feedback App entry point.
4
+ *
5
+ * Modes:
6
+ * --stdio : stdio transport (default, for Claude Desktop / Cursor)
7
+ * --http : HTTP transport on port 3001 (for Claude Web / remote testing)
8
+ *
9
+ * The blocking feedback pattern (interactive_feedback waits for submit_feedback)
10
+ * requires a persistent connection, so stdio is the primary transport.
11
+ * HTTP mode creates a new server per request for stateless tool calls.
12
+ */
13
+ export {};