@aioproductoscom/mcp 0.6.0 → 0.8.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 +4 -0
- package/dist/client.js +18 -0
- package/dist/index.js +9 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,11 +52,15 @@ at a self-hosted platform.
|
|
|
52
52
|
| `get_product_brain` | a grounded read-only snapshot of your product (revenue, accounts, web + product analytics, features, signals, open work) |
|
|
53
53
|
| `analyze_funnel` | build an ordered conversion funnel from your events (users per step, conversion, drop-off); omit steps to list available events |
|
|
54
54
|
| `get_retention` | weekly cohort retention — who comes back, week over week |
|
|
55
|
+
| `analyze_paths` | user paths (Sankey) — what people do after a start event, with drop-off |
|
|
55
56
|
| `list_conversations` | the support-chat inbox (open threads, visitor, topic, status) |
|
|
56
57
|
| `get_conversation` | one support thread + its full message history |
|
|
57
58
|
| `reply_to_conversation` | reply to a visitor (**visible in their chat widget**, sent as you) |
|
|
58
59
|
| `add_note` | internal triage note on a conversation (never shown to the visitor) |
|
|
59
60
|
| `resolve_conversation` | mark a conversation resolved |
|
|
61
|
+
| `list_bookings` | scheduled calls/meetings (upcoming by default) |
|
|
62
|
+
| `cancel_booking` | cancel a booking (frees the slot, cancels the meeting) |
|
|
63
|
+
| `reschedule_booking` | move a booking to a new open slot |
|
|
60
64
|
|
|
61
65
|
> For an assignable **coding teammate** (Backend / Frontend / Mobile / QA that
|
|
62
66
|
> opens PRs in your repo), install the separate
|
package/dist/client.js
CHANGED
|
@@ -81,6 +81,17 @@ export class PlatformClient {
|
|
|
81
81
|
const qs = p.toString();
|
|
82
82
|
return this.req(`/api/me/retention${qs ? `?${qs}` : ""}`);
|
|
83
83
|
}
|
|
84
|
+
paths(opts) {
|
|
85
|
+
const p = new URLSearchParams();
|
|
86
|
+
if (opts.productId)
|
|
87
|
+
p.set("product_id", opts.productId);
|
|
88
|
+
if (opts.window)
|
|
89
|
+
p.set("window", String(opts.window));
|
|
90
|
+
if (opts.start)
|
|
91
|
+
p.set("start", opts.start);
|
|
92
|
+
const qs = p.toString();
|
|
93
|
+
return this.req(`/api/me/paths${qs ? `?${qs}` : ""}`);
|
|
94
|
+
}
|
|
84
95
|
listConversations(opts) {
|
|
85
96
|
const p = new URLSearchParams();
|
|
86
97
|
if (opts.productId)
|
|
@@ -96,4 +107,11 @@ export class PlatformClient {
|
|
|
96
107
|
inboxAction(body) {
|
|
97
108
|
return this.req("/api/me/inbox", { method: "POST", body: JSON.stringify(body) });
|
|
98
109
|
}
|
|
110
|
+
listBookings(opts) {
|
|
111
|
+
const qs = opts.include === "all" ? "?include=all" : "";
|
|
112
|
+
return this.req(`/api/me/scheduling${qs}`);
|
|
113
|
+
}
|
|
114
|
+
schedulingAction(body) {
|
|
115
|
+
return this.req("/api/me/scheduling", { method: "POST", body: JSON.stringify(body) });
|
|
116
|
+
}
|
|
99
117
|
}
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ function text(data) {
|
|
|
17
17
|
],
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
const server = new McpServer({ name: "productos", version: "0.
|
|
20
|
+
const server = new McpServer({ name: "productos", version: "0.8.0" }, {
|
|
21
21
|
instructions: "You manage ProductOS PM tickets on behalf of the connected member — the board is the team's " +
|
|
22
22
|
"source of truth, so work precisely. Resolve names to ids with pm_meta before create_task / " +
|
|
23
23
|
"update_task; never guess an id. Link a task to the spine (feature_id / insight_id) whenever the " +
|
|
@@ -57,11 +57,19 @@ server.tool("analyze_funnel", "Build a conversion funnel from the product's own
|
|
|
57
57
|
window_days: z.number().optional(),
|
|
58
58
|
}, async (a) => text(await client.funnel({ steps: a.steps, productId: a.product_id, window: a.window_days })));
|
|
59
59
|
server.tool("get_retention", "Weekly cohort retention for the product: users grouped by their first-seen week, with the share returning each week after. Optional product_id (defaults to the primary product) and window_days (default 56 = 8 weekly cohorts).", { product_id: z.string().optional(), window_days: z.number().optional() }, async (a) => text(await client.retention({ productId: a.product_id, window: a.window_days })));
|
|
60
|
+
server.tool("analyze_paths", "Trace what users do AFTER a start event — the journey flow (Sankey) from the product's own events, so YOU can reason about real behaviour on your model. Returns nodes (the event at each depth, with distinct users + share of journeys) and links (source→target with how many users took that step), including where people drop off ('(exit)') and the collapsed long tail ('(other)'). Pass `start` to anchor on a specific event, or omit it to anchor on the most common journey start. Optional product_id (defaults to the primary product) and window_days (default 30).", {
|
|
61
|
+
start: z.string().optional(),
|
|
62
|
+
product_id: z.string().optional(),
|
|
63
|
+
window_days: z.number().optional(),
|
|
64
|
+
}, async (a) => text(await client.paths({ start: a.start, productId: a.product_id, window: a.window_days })));
|
|
60
65
|
server.tool("list_conversations", "List support-chat conversations in the inbox (open + snoozed by default; pass status='all' to include closed). Each has id, visitor, topic, status, and last activity. Optional product_id to scope to one product.", { product_id: z.string().optional(), status: z.enum(["all"]).optional() }, async (a) => text(await client.listConversations({ productId: a.product_id, status: a.status })));
|
|
61
66
|
server.tool("get_conversation", "Read one support conversation: the visitor + the full message thread (visitor, agent, and internal notes), oldest first.", { conversation_id: z.string() }, async (a) => text(await client.getConversation(a.conversation_id)));
|
|
62
67
|
server.tool("reply_to_conversation", "Send a reply into a support conversation. This message IS VISIBLE TO THE VISITOR in the chat widget — it goes out as you (the member who owns this token). Use add_note for internal triage you don't want the visitor to see.", { conversation_id: z.string(), body: z.string() }, async (a) => text(await client.inboxAction({ action: "reply", conversation_id: a.conversation_id, body: a.body })));
|
|
63
68
|
server.tool("add_note", "Add an INTERNAL note to a support conversation — visible only in the inbox, never to the visitor. Use to record triage, context, or a handoff for a human.", { conversation_id: z.string(), body: z.string() }, async (a) => text(await client.inboxAction({ action: "note", conversation_id: a.conversation_id, body: a.body })));
|
|
64
69
|
server.tool("resolve_conversation", "Mark a support conversation resolved (status='closed'). A later visitor message reopens it.", { conversation_id: z.string() }, async (a) => text(await client.inboxAction({ action: "resolve", conversation_id: a.conversation_id })));
|
|
70
|
+
server.tool("list_bookings", "List scheduled bookings (calls/meetings) — upcoming confirmed ones by default; pass include='all' for past + cancelled. Each has id, event type, guest, host, start/end, and status.", { include: z.enum(["all"]).optional() }, async (a) => text(await client.listBookings({ include: a.include })));
|
|
71
|
+
server.tool("cancel_booking", "Cancel a booking by id — frees the slot and cancels the linked meeting. Cannot cancel a meeting that has already started.", { booking_id: z.string() }, async (a) => text(await client.schedulingAction({ action: "cancel", booking_id: a.booking_id })));
|
|
72
|
+
server.tool("reschedule_booking", "Move a booking to a new start time (ISO 8601, e.g. 2026-06-20T15:00:00Z). The new time must be a currently-open slot for that event type. Cannot reschedule a meeting that has already started.", { booking_id: z.string(), start: z.string() }, async (a) => text(await client.schedulingAction({ action: "reschedule", booking_id: a.booking_id, start: a.start })));
|
|
65
73
|
async function main() {
|
|
66
74
|
await server.connect(new StdioServerTransport());
|
|
67
75
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aioproductoscom/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "ProductOS MCP — manage tickets, read your product brain + analytics, and run the support inbox from Claude Code, Cursor, Codex, and any MCP host.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|