@aioproductoscom/mcp 0.7.0 → 0.9.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 +5 -0
- package/dist/client.js +32 -0
- package/dist/index.js +10 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,6 +52,7 @@ 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) |
|
|
@@ -60,6 +61,10 @@ at a self-hosted platform.
|
|
|
60
61
|
| `list_bookings` | scheduled calls/meetings (upcoming by default) |
|
|
61
62
|
| `cancel_booking` | cancel a booking (frees the slot, cancels the meeting) |
|
|
62
63
|
| `reschedule_booking` | move a booking to a new open slot |
|
|
64
|
+
| `list_channels` | the team Comms channels you belong to |
|
|
65
|
+
| `read_channel` | recent messages in a channel (catch up before replying) |
|
|
66
|
+
| `post_to_channel` | post into a team channel — visible live to teammates, as you |
|
|
67
|
+
| `reply_in_channel` | reply in a thread under a message |
|
|
63
68
|
|
|
64
69
|
> For an assignable **coding teammate** (Backend / Frontend / Mobile / QA that
|
|
65
70
|
> 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)
|
|
@@ -103,4 +114,25 @@ export class PlatformClient {
|
|
|
103
114
|
schedulingAction(body) {
|
|
104
115
|
return this.req("/api/me/scheduling", { method: "POST", body: JSON.stringify(body) });
|
|
105
116
|
}
|
|
117
|
+
listChannels() {
|
|
118
|
+
return this.req("/api/me/comms");
|
|
119
|
+
}
|
|
120
|
+
readChannel(channelId, limit) {
|
|
121
|
+
const p = new URLSearchParams({ channel_id: channelId });
|
|
122
|
+
if (limit)
|
|
123
|
+
p.set("limit", String(limit));
|
|
124
|
+
return this.req(`/api/me/comms?${p.toString()}`);
|
|
125
|
+
}
|
|
126
|
+
postToChannel(channelId, body) {
|
|
127
|
+
return this.req("/api/me/comms", {
|
|
128
|
+
method: "POST",
|
|
129
|
+
body: JSON.stringify({ action: "post", channel_id: channelId, body }),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
replyInChannel(channelId, parentId, body) {
|
|
133
|
+
return this.req("/api/me/comms", {
|
|
134
|
+
method: "POST",
|
|
135
|
+
body: JSON.stringify({ action: "reply", channel_id: channelId, parent_id: parentId, body }),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
106
138
|
}
|
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.9.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,6 +57,11 @@ 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 })));
|
|
@@ -65,6 +70,10 @@ server.tool("resolve_conversation", "Mark a support conversation resolved (statu
|
|
|
65
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 })));
|
|
66
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 })));
|
|
67
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 })));
|
|
73
|
+
server.tool("list_channels", "List the team Comms channels you (this token's member) belong to — id, name, kind, topic. These are the channels you can read and post into. An admin adds you to a channel in ProductOS → Comms.", {}, async () => text(await client.listChannels()));
|
|
74
|
+
server.tool("read_channel", "Read recent messages in a Comms channel you belong to (oldest→newest), so you can catch up before replying. Pass the channel_id from list_channels.", { channel_id: z.string(), limit: z.number().optional() }, async (a) => text(await client.readChannel(a.channel_id, a.limit)));
|
|
75
|
+
server.tool("post_to_channel", "Post a message into a team Comms channel you belong to. It goes out as you (this token's member) and appears live for your teammates — use it to tell the team what you did, share a link, or ask a question. Only works for channels you're a member of (see list_channels).", { channel_id: z.string(), body: z.string() }, async (a) => text(await client.postToChannel(a.channel_id, a.body)));
|
|
76
|
+
server.tool("reply_in_channel", "Reply in a thread under a specific message in a Comms channel you belong to. Pass the parent message's id (from read_channel) as parent_id.", { channel_id: z.string(), parent_id: z.string(), body: z.string() }, async (a) => text(await client.replyInChannel(a.channel_id, a.parent_id, a.body)));
|
|
68
77
|
async function main() {
|
|
69
78
|
await server.connect(new StdioServerTransport());
|
|
70
79
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aioproductoscom/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.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",
|