super-feedback-mcp 0.2.1 ā 0.2.5
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 +5 -5
- package/dist/index.js +35 -4
- package/package.json +2 -2
- package/src/index.ts +37 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SuperFeedback MCP Server
|
|
2
2
|
|
|
3
|
-
An MCP (Model Context Protocol) server that enables AI agents in Cursor to query and resolve client feedback from
|
|
3
|
+
An MCP (Model Context Protocol) server that enables AI agents in Cursor to query and resolve client feedback from SuperFeedback projects.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -57,7 +57,7 @@ Or if published to npm:
|
|
|
57
57
|
*At least one of `ACCESS_CODE` or `ADMIN_CODE` is required. For full functionality (read + resolve), provide both.
|
|
58
58
|
|
|
59
59
|
**Where to find these codes:**
|
|
60
|
-
- Go to your
|
|
60
|
+
- Go to your SuperFeedback dashboard
|
|
61
61
|
- Select your project
|
|
62
62
|
- Click "Settings" or the gear icon
|
|
63
63
|
- Copy the "Access Code" and "Admin Code"
|
|
@@ -121,7 +121,7 @@ The agent will:
|
|
|
121
121
|
|
|
122
122
|
## How It Works
|
|
123
123
|
|
|
124
|
-
The MCP server connects to your
|
|
124
|
+
The MCP server connects to your SuperFeedback project via the Convex API using your access code. It transforms the raw feedback data into AI-friendly format with:
|
|
125
125
|
|
|
126
126
|
- **Element identification**: Multiple selector strategies (ID, test ID, CSS path, XPath)
|
|
127
127
|
- **Route mapping**: Extracts page path and suggests likely source files
|
|
@@ -150,7 +150,7 @@ Make sure you've set the `SUPER_FEEDBACK_ACCESS_CODE` in your MCP config's `env`
|
|
|
150
150
|
|
|
151
151
|
### "API error: 401"
|
|
152
152
|
|
|
153
|
-
Your access code is invalid or expired. Check your project settings in
|
|
153
|
+
Your access code is invalid or expired. Check your project settings in SuperFeedback.
|
|
154
154
|
|
|
155
155
|
### "API error: 404"
|
|
156
156
|
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ async function callConvexAPI(endpoint, options) {
|
|
|
39
39
|
// Create MCP server
|
|
40
40
|
const server = new McpServer({
|
|
41
41
|
name: "super-feedback",
|
|
42
|
-
version: "0.2.
|
|
42
|
+
version: "0.2.5",
|
|
43
43
|
});
|
|
44
44
|
// Tool 1: Get feedback summary (lightweight overview)
|
|
45
45
|
server.registerTool("get_feedback_summary", {
|
|
@@ -50,7 +50,13 @@ Returns:
|
|
|
50
50
|
- Total comment count
|
|
51
51
|
- Open (unresolved) count
|
|
52
52
|
- Resolved count
|
|
53
|
-
- List of
|
|
53
|
+
- List of comments with index, ID, feedback text, status, and page path
|
|
54
|
+
|
|
55
|
+
Comments are sorted by createdAt ASCENDING (oldest first), so:
|
|
56
|
+
- Index 1 = the FIRST/OLDEST comment added
|
|
57
|
+
- Index N = the NEWEST/most recent comment
|
|
58
|
+
|
|
59
|
+
This matches the order users see comments in the UI, so when a user says "fix comment #3", you can use index 3 to find the exact comment they're referring to.
|
|
54
60
|
|
|
55
61
|
Use this first to understand what feedback exists, then use get_comment_details for full context on specific comments.`,
|
|
56
62
|
inputSchema: {
|
|
@@ -201,8 +207,33 @@ Use this after get_feedback_summary to dive into a specific comment.`,
|
|
|
201
207
|
text += `\n ${change.property}: ${change.oldValue} ā ${change.newValue}`;
|
|
202
208
|
});
|
|
203
209
|
}
|
|
210
|
+
// Note if there are images attached
|
|
211
|
+
if (c.imageUrls && c.imageUrls.length > 0) {
|
|
212
|
+
text += `\n\nš¼ļø Attached Images: ${c.imageUrls.length} image(s)`;
|
|
213
|
+
}
|
|
214
|
+
// Fetch images and convert to base64 for MCP ImageContent
|
|
215
|
+
const imageContents = [];
|
|
216
|
+
if (c.imageUrls && c.imageUrls.length > 0) {
|
|
217
|
+
for (const url of c.imageUrls) {
|
|
218
|
+
try {
|
|
219
|
+
const imgResponse = await fetch(url);
|
|
220
|
+
if (imgResponse.ok) {
|
|
221
|
+
const buffer = await imgResponse.arrayBuffer();
|
|
222
|
+
const base64 = Buffer.from(buffer).toString("base64");
|
|
223
|
+
const mimeType = imgResponse.headers.get("content-type") || "image/png";
|
|
224
|
+
imageContents.push({ type: "image", data: base64, mimeType });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Skip images that fail to fetch
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
204
232
|
return {
|
|
205
|
-
content: [
|
|
233
|
+
content: [
|
|
234
|
+
{ type: "text", text },
|
|
235
|
+
...imageContents,
|
|
236
|
+
],
|
|
206
237
|
structuredContent: { found: true, comment: c },
|
|
207
238
|
};
|
|
208
239
|
}
|
|
@@ -271,7 +302,7 @@ async function main() {
|
|
|
271
302
|
const transport = new StdioServerTransport();
|
|
272
303
|
await server.connect(transport);
|
|
273
304
|
// Log to stderr so it doesn't interfere with MCP protocol on stdout
|
|
274
|
-
console.error("
|
|
305
|
+
console.error("SuperFeedback MCP server running...");
|
|
275
306
|
}
|
|
276
307
|
main().catch((error) => {
|
|
277
308
|
console.error("Fatal error:", error);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "super-feedback-mcp",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "MCP server for
|
|
3
|
+
"version": "0.2.5",
|
|
4
|
+
"description": "MCP server for SuperFeedback - enables AI agents to query and resolve client feedback",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
package/src/index.ts
CHANGED
|
@@ -72,6 +72,7 @@ interface FullCommentDetails {
|
|
|
72
72
|
elementText: string;
|
|
73
73
|
label?: string;
|
|
74
74
|
}>;
|
|
75
|
+
imageUrls?: string[];
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
// Configuration from environment
|
|
@@ -115,7 +116,7 @@ async function callConvexAPI<T>(endpoint: string, options?: RequestInit): Promis
|
|
|
115
116
|
// Create MCP server
|
|
116
117
|
const server = new McpServer({
|
|
117
118
|
name: "super-feedback",
|
|
118
|
-
version: "0.2.
|
|
119
|
+
version: "0.2.5",
|
|
119
120
|
});
|
|
120
121
|
|
|
121
122
|
// Tool 1: Get feedback summary (lightweight overview)
|
|
@@ -129,7 +130,13 @@ Returns:
|
|
|
129
130
|
- Total comment count
|
|
130
131
|
- Open (unresolved) count
|
|
131
132
|
- Resolved count
|
|
132
|
-
- List of
|
|
133
|
+
- List of comments with index, ID, feedback text, status, and page path
|
|
134
|
+
|
|
135
|
+
Comments are sorted by createdAt ASCENDING (oldest first), so:
|
|
136
|
+
- Index 1 = the FIRST/OLDEST comment added
|
|
137
|
+
- Index N = the NEWEST/most recent comment
|
|
138
|
+
|
|
139
|
+
This matches the order users see comments in the UI, so when a user says "fix comment #3", you can use index 3 to find the exact comment they're referring to.
|
|
133
140
|
|
|
134
141
|
Use this first to understand what feedback exists, then use get_comment_details for full context on specific comments.`,
|
|
135
142
|
inputSchema: {
|
|
@@ -303,8 +310,34 @@ Use this after get_feedback_summary to dive into a specific comment.`,
|
|
|
303
310
|
});
|
|
304
311
|
}
|
|
305
312
|
|
|
313
|
+
// Note if there are images attached
|
|
314
|
+
if (c.imageUrls && c.imageUrls.length > 0) {
|
|
315
|
+
text += `\n\nš¼ļø Attached Images: ${c.imageUrls.length} image(s)`;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Fetch images and convert to base64 for MCP ImageContent
|
|
319
|
+
const imageContents: Array<{ type: "image"; data: string; mimeType: string }> = [];
|
|
320
|
+
if (c.imageUrls && c.imageUrls.length > 0) {
|
|
321
|
+
for (const url of c.imageUrls) {
|
|
322
|
+
try {
|
|
323
|
+
const imgResponse = await fetch(url);
|
|
324
|
+
if (imgResponse.ok) {
|
|
325
|
+
const buffer = await imgResponse.arrayBuffer();
|
|
326
|
+
const base64 = Buffer.from(buffer).toString("base64");
|
|
327
|
+
const mimeType = imgResponse.headers.get("content-type") || "image/png";
|
|
328
|
+
imageContents.push({ type: "image", data: base64, mimeType });
|
|
329
|
+
}
|
|
330
|
+
} catch {
|
|
331
|
+
// Skip images that fail to fetch
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
306
336
|
return {
|
|
307
|
-
content: [
|
|
337
|
+
content: [
|
|
338
|
+
{ type: "text", text },
|
|
339
|
+
...imageContents,
|
|
340
|
+
],
|
|
308
341
|
structuredContent: { found: true, comment: c },
|
|
309
342
|
};
|
|
310
343
|
} catch (error) {
|
|
@@ -382,7 +415,7 @@ async function main() {
|
|
|
382
415
|
await server.connect(transport);
|
|
383
416
|
|
|
384
417
|
// Log to stderr so it doesn't interfere with MCP protocol on stdout
|
|
385
|
-
console.error("
|
|
418
|
+
console.error("SuperFeedback MCP server running...");
|
|
386
419
|
}
|
|
387
420
|
|
|
388
421
|
main().catch((error) => {
|