@easyfunnel/mcp 0.1.9 → 0.1.11
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/dist/index.js +129 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -94,6 +94,14 @@ var ApiClient = class {
|
|
|
94
94
|
body: JSON.stringify(config)
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
+
async getConversations(projectId, params) {
|
|
98
|
+
const searchParams = new URLSearchParams();
|
|
99
|
+
if (params.limit) searchParams.set("limit", params.limit.toString());
|
|
100
|
+
if (params.session_id) searchParams.set("session_id", params.session_id);
|
|
101
|
+
return this.request(
|
|
102
|
+
`/projects/${projectId}/conversations?${searchParams.toString()}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
97
105
|
async queryEvents(projectId, params) {
|
|
98
106
|
const searchParams = new URLSearchParams();
|
|
99
107
|
searchParams.set("query_type", params.query_type);
|
|
@@ -824,8 +832,8 @@ var queryEventsDefinition = {
|
|
|
824
832
|
project_id: { type: "string", description: "Project ID" },
|
|
825
833
|
query_type: {
|
|
826
834
|
type: "string",
|
|
827
|
-
enum: ["count", "recent", "breakdown", "section_engagement", "traffic_sources"],
|
|
828
|
-
description:
|
|
835
|
+
enum: ["count", "recent", "breakdown", "section_engagement", "traffic_sources", "engagement"],
|
|
836
|
+
description: 'Type of query. Use "engagement" to get scroll depth and engaged time metrics.'
|
|
829
837
|
},
|
|
830
838
|
event_name: {
|
|
831
839
|
type: "string",
|
|
@@ -863,7 +871,9 @@ async function queryEvents(client2, args) {
|
|
|
863
871
|
`;
|
|
864
872
|
output += ` Unique sessions: ${data.unique_sessions}
|
|
865
873
|
`;
|
|
866
|
-
output += ` Unique
|
|
874
|
+
output += ` Unique visitors: ${data.unique_visitors}
|
|
875
|
+
`;
|
|
876
|
+
output += ` Identified users: ${data.identified_users}
|
|
867
877
|
`;
|
|
868
878
|
} else if (args.query_type === "recent") {
|
|
869
879
|
output = `Recent events:
|
|
@@ -873,8 +883,43 @@ async function queryEvents(client2, args) {
|
|
|
873
883
|
output += ` [${event.created_at}] ${event.event_name}`;
|
|
874
884
|
if (event.properties?.url) output += ` \u2014 ${event.properties.url}`;
|
|
875
885
|
output += "\n";
|
|
886
|
+
if (event.properties) {
|
|
887
|
+
const props = { ...event.properties };
|
|
888
|
+
delete props.url;
|
|
889
|
+
const keys = Object.keys(props);
|
|
890
|
+
if (keys.length > 0) {
|
|
891
|
+
output += ` properties: ${JSON.stringify(props)}
|
|
892
|
+
`;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
876
895
|
}
|
|
877
896
|
if (!data.events?.length) output += " No events found.\n";
|
|
897
|
+
} else if (args.query_type === "engagement") {
|
|
898
|
+
output = `Engagement metrics (${args.time_range || "7d"}):
|
|
899
|
+
|
|
900
|
+
`;
|
|
901
|
+
output += ` Avg scroll depth: ${data.avg_scroll_depth}%
|
|
902
|
+
`;
|
|
903
|
+
output += ` Avg engaged time: ${data.avg_engaged_time}s
|
|
904
|
+
`;
|
|
905
|
+
output += ` Total engagement events: ${data.total_events}
|
|
906
|
+
|
|
907
|
+
`;
|
|
908
|
+
output += ` Scroll depth distribution:
|
|
909
|
+
`;
|
|
910
|
+
for (const bucket of data.scroll_depth_distribution || []) {
|
|
911
|
+
output += ` ${bucket.bucket}: ${bucket.count} events
|
|
912
|
+
`;
|
|
913
|
+
}
|
|
914
|
+
if (data.top_pages?.length) {
|
|
915
|
+
output += `
|
|
916
|
+
Top pages by scroll depth:
|
|
917
|
+
`;
|
|
918
|
+
for (const page of data.top_pages) {
|
|
919
|
+
output += ` ${page.url}: ${page.avg_scroll_depth}% avg, ${page.count} events
|
|
920
|
+
`;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
878
923
|
} else if (args.query_type === "section_engagement") {
|
|
879
924
|
output = `Section engagement (${args.time_range || "7d"}):
|
|
880
925
|
|
|
@@ -2117,6 +2162,83 @@ The chat widget will appear as a floating bubble in the bottom-right corner of y
|
|
|
2117
2162
|
};
|
|
2118
2163
|
}
|
|
2119
2164
|
|
|
2165
|
+
// src/tools/query-conversations.ts
|
|
2166
|
+
var queryConversationsDefinition = {
|
|
2167
|
+
name: "query_conversations",
|
|
2168
|
+
description: "Read chat widget conversations from visitors. Lists recent conversations with previews, or fetches full message transcript for a specific session.",
|
|
2169
|
+
inputSchema: {
|
|
2170
|
+
type: "object",
|
|
2171
|
+
properties: {
|
|
2172
|
+
project_id: { type: "string", description: "Project ID" },
|
|
2173
|
+
session_id: {
|
|
2174
|
+
type: "string",
|
|
2175
|
+
description: "Specific chat session ID to fetch full transcript. If omitted, lists recent conversations."
|
|
2176
|
+
},
|
|
2177
|
+
limit: {
|
|
2178
|
+
type: "number",
|
|
2179
|
+
description: "Max conversations to return (default: 20, max: 50)"
|
|
2180
|
+
}
|
|
2181
|
+
},
|
|
2182
|
+
required: ["project_id"]
|
|
2183
|
+
}
|
|
2184
|
+
};
|
|
2185
|
+
async function queryConversations(client2, args) {
|
|
2186
|
+
const data = await client2.getConversations(args.project_id, {
|
|
2187
|
+
limit: args.limit,
|
|
2188
|
+
session_id: args.session_id
|
|
2189
|
+
});
|
|
2190
|
+
let output;
|
|
2191
|
+
if (args.session_id) {
|
|
2192
|
+
const s = data.session;
|
|
2193
|
+
output = `Conversation with ${s.user_email || "Anonymous (" + s.visitor_id.slice(0, 8) + ")"}
|
|
2194
|
+
`;
|
|
2195
|
+
output += `Country: ${s.country || "unknown"} | Device: ${s.device || "unknown"} | Browser: ${s.browser || "unknown"}
|
|
2196
|
+
`;
|
|
2197
|
+
output += `First page: ${s.first_page || "unknown"}
|
|
2198
|
+
`;
|
|
2199
|
+
output += `Started: ${s.created_at}
|
|
2200
|
+
`;
|
|
2201
|
+
output += `\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2202
|
+
|
|
2203
|
+
`;
|
|
2204
|
+
for (const msg of data.messages || []) {
|
|
2205
|
+
const label = msg.role === "user" ? "\u{1F464} Visitor" : "\u{1F916} Assistant";
|
|
2206
|
+
output += `${label}:
|
|
2207
|
+
${msg.content}
|
|
2208
|
+
`;
|
|
2209
|
+
if (msg.page_url) output += ` [on ${msg.page_url}]
|
|
2210
|
+
`;
|
|
2211
|
+
output += "\n";
|
|
2212
|
+
}
|
|
2213
|
+
if (!data.messages?.length) output += "No messages in this conversation.\n";
|
|
2214
|
+
} else {
|
|
2215
|
+
const sessions = data.sessions || [];
|
|
2216
|
+
output = `Chat conversations (${sessions.length} total):
|
|
2217
|
+
|
|
2218
|
+
`;
|
|
2219
|
+
for (const s of sessions) {
|
|
2220
|
+
const visitor = s.user_email || `Anonymous (${s.visitor_id.slice(0, 8)})`;
|
|
2221
|
+
const country = s.country || "??";
|
|
2222
|
+
const device = s.device || "?";
|
|
2223
|
+
output += `\u2022 ${visitor} \u2014 ${country}, ${device}, ${s.message_count} msgs
|
|
2224
|
+
`;
|
|
2225
|
+
output += ` ID: ${s.id}
|
|
2226
|
+
`;
|
|
2227
|
+
if (s.preview) output += ` "${s.preview}"
|
|
2228
|
+
`;
|
|
2229
|
+
output += ` First page: ${s.first_page || "?"} | Last active: ${s.last_message_at}
|
|
2230
|
+
|
|
2231
|
+
`;
|
|
2232
|
+
}
|
|
2233
|
+
if (sessions.length === 0) {
|
|
2234
|
+
output += "No conversations yet.\n";
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
return {
|
|
2238
|
+
content: [{ type: "text", text: output }]
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2120
2242
|
// src/index.ts
|
|
2121
2243
|
var apiKey = process.env.EASYFUNNEL_API_KEY;
|
|
2122
2244
|
if (!apiKey) {
|
|
@@ -2147,7 +2269,8 @@ server.setRequestHandler(import_types.ListToolsRequestSchema, async () => ({
|
|
|
2147
2269
|
queryEventsDefinition,
|
|
2148
2270
|
deleteFunnelDefinition,
|
|
2149
2271
|
updateFunnelDefinition,
|
|
2150
|
-
setupChatWidgetDefinition
|
|
2272
|
+
setupChatWidgetDefinition,
|
|
2273
|
+
queryConversationsDefinition
|
|
2151
2274
|
]
|
|
2152
2275
|
}));
|
|
2153
2276
|
server.setRequestHandler(import_types.CallToolRequestSchema, async (request) => {
|
|
@@ -2183,6 +2306,8 @@ server.setRequestHandler(import_types.CallToolRequestSchema, async (request) =>
|
|
|
2183
2306
|
return updateFunnel(client, args);
|
|
2184
2307
|
case "setup_chat_widget":
|
|
2185
2308
|
return setupChatWidget(client, args);
|
|
2309
|
+
case "query_conversations":
|
|
2310
|
+
return queryConversations(client, args);
|
|
2186
2311
|
default:
|
|
2187
2312
|
throw new Error(`Unknown tool: ${name}`);
|
|
2188
2313
|
}
|