@pergy-ai/mcp 0.2.1 → 0.3.1
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 +1 -1
- package/dist/index.js +19 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ It talks to the hosted backend by default — no config needed. Set
|
|
|
34
34
|
|
|
35
35
|
## Tools
|
|
36
36
|
|
|
37
|
-
- **`notify_user`** — notify the user (
|
|
37
|
+
- **`notify_user`** — notify the user (context: title + description chunks, plus optional options — each an answerable choice that can carry a sandboxed `html` or `image` preview for visual "pick one" decisions — visuals, `urgency`, and `parentId` for a clarification). Returns a request id + thread id. If a reply comes back as `{kind:'clarify', chunks:[...]}`, respond via notify_user with the SAME threadId and an expanded description.
|
|
38
38
|
- **`await_reply`** — wait for the user's reply to a specific notification (pass its id). Scoped: will not return replies meant for other notifications. Returns `reply` / `remind` / `idle`.
|
|
39
39
|
- **`check_replies`** — catch-up sweep: returns replies you haven't consumed yet (now marked seen) plus still-pending notifications.
|
|
40
40
|
- **`poll_answer`** — fetch the answer to a specific request by id.
|
package/dist/index.js
CHANGED
|
@@ -11,10 +11,9 @@ import { execSync } from "child_process";
|
|
|
11
11
|
|
|
12
12
|
// ../../packages/schema/dist/index.js
|
|
13
13
|
import { z } from "zod";
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
long: z.string().describe("A standalone version of 1-3 paragraphs.")
|
|
14
|
+
var ContextSchema = z.object({
|
|
15
|
+
title: z.string().min(1).describe("One-line headline of what you need (required, non-empty)."),
|
|
16
|
+
description: z.array(z.string().min(1)).min(1).describe("Semantic chunks of detail (each a standalone, non-empty piece). The user can select chunks to ask you to expand.")
|
|
18
17
|
});
|
|
19
18
|
var OptionSchema = z.object({
|
|
20
19
|
id: z.string(),
|
|
@@ -36,7 +35,7 @@ var AgentSchema = z.object({
|
|
|
36
35
|
name: z.string()
|
|
37
36
|
});
|
|
38
37
|
var NotifyRequestSchema = z.object({
|
|
39
|
-
context:
|
|
38
|
+
context: ContextSchema,
|
|
40
39
|
options: z.array(OptionSchema).optional(),
|
|
41
40
|
visuals: z.array(VisualSchema).optional(),
|
|
42
41
|
agent: AgentSchema,
|
|
@@ -47,10 +46,13 @@ var NotifyRequestSchema = z.object({
|
|
|
47
46
|
/** Continue an existing conversation; omitted = start a new thread. */
|
|
48
47
|
threadId: z.string().uuid().optional(),
|
|
49
48
|
createdAt: z.string().datetime(),
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
urgency: z.enum(["inbox", "call"]).default("inbox").describe(
|
|
50
|
+
"'inbox' (default) = sits silently in the inbox for the user to get to. 'call' = rings the user's phone now (a CallKit voice call) \u2014 use only when you genuinely need them in the moment (blocked and waiting, time-sensitive). context.title becomes what they see on the ring, so make it specific."
|
|
51
|
+
),
|
|
52
52
|
/** The request this one was spawned from, for a clarification. */
|
|
53
|
-
parentId: z.string().optional()
|
|
53
|
+
parentId: z.string().optional(),
|
|
54
|
+
/** How the user answers the options: pick one (default), pick several, or pick & order. */
|
|
55
|
+
select: z.enum(["one", "many", "rank"]).default("one")
|
|
54
56
|
});
|
|
55
57
|
var NotifyStatusSchema = z.enum(["pending", "answered", "ignored"]);
|
|
56
58
|
var AgentStateSchema = z.enum(["idle", "in_progress", "completed", "needs_input"]);
|
|
@@ -60,7 +62,10 @@ var SetTaskStateSchema = z.object({
|
|
|
60
62
|
var UserAnswerSchema = z.discriminatedUnion("kind", [
|
|
61
63
|
z.object({ kind: z.literal("option"), optionId: z.string() }),
|
|
62
64
|
z.object({ kind: z.literal("text"), text: z.string() }),
|
|
63
|
-
z.object({ kind: z.literal("ignored") })
|
|
65
|
+
z.object({ kind: z.literal("ignored") }),
|
|
66
|
+
z.object({ kind: z.literal("multi"), optionIds: z.array(z.string()) }),
|
|
67
|
+
z.object({ kind: z.literal("ranked"), optionIds: z.array(z.string()) }),
|
|
68
|
+
z.object({ kind: z.literal("clarify"), chunks: z.array(z.string()).min(1) })
|
|
64
69
|
]);
|
|
65
70
|
var AwaitItemSchema = z.discriminatedUnion("type", [
|
|
66
71
|
z.object({
|
|
@@ -102,7 +107,7 @@ var UserResponseSchema = z.object({
|
|
|
102
107
|
var InboxItemSchema = z.object({
|
|
103
108
|
id: z.string(),
|
|
104
109
|
status: NotifyStatusSchema,
|
|
105
|
-
context:
|
|
110
|
+
context: ContextSchema,
|
|
106
111
|
options: z.array(OptionSchema).optional(),
|
|
107
112
|
visuals: z.array(VisualSchema).optional(),
|
|
108
113
|
agent: z.string(),
|
|
@@ -112,7 +117,8 @@ var InboxItemSchema = z.object({
|
|
|
112
117
|
createdAt: z.string().datetime(),
|
|
113
118
|
snoozedUntil: z.string().datetime().optional(),
|
|
114
119
|
agentState: AgentStateSchema.default("idle"),
|
|
115
|
-
parentId: z.string().optional()
|
|
120
|
+
parentId: z.string().optional(),
|
|
121
|
+
select: z.enum(["one", "many", "rank"]).default("one")
|
|
116
122
|
});
|
|
117
123
|
var SnoozeRequestSchema = z.object({
|
|
118
124
|
requestId: z.string(),
|
|
@@ -264,14 +270,14 @@ var server = new Server(
|
|
|
264
270
|
{ name: "pergy", version: "0.0.0" },
|
|
265
271
|
{
|
|
266
272
|
capabilities: { tools: {} },
|
|
267
|
-
instructions: "On startup, call check_replies once to pick up any replies or pending work you missed while away. To wait for the answer to something you just asked, call await_reply with that notification's id \u2014 it's scoped to that one request, so it never returns replies meant for other requests. Use check_replies again only when re-booting or after waiting a long time on something else. Never end a turn that still needs the user without notify_user + await_reply."
|
|
273
|
+
instructions: "On startup, call check_replies once to pick up any replies or pending work you missed while away. To wait for the answer to something you just asked, call await_reply with that notification's id \u2014 it's scoped to that one request, so it never returns replies meant for other requests. Use check_replies again only when re-booting or after waiting a long time on something else. Never end a turn that still needs the user without notify_user + await_reply. If a reply comes back as { kind: 'clarify', chunks: [...] }, the user wants more detail on those chunks \u2014 respond by calling notify_user again with the SAME threadId and an expanded description covering them."
|
|
268
274
|
}
|
|
269
275
|
);
|
|
270
276
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
271
277
|
tools: [
|
|
272
278
|
{
|
|
273
279
|
name: "notify_user",
|
|
274
|
-
description: "Notify the user via Pergy and get a request id to poll for their answer. Provide context
|
|
280
|
+
description: "Notify the user via Pergy and get a request id to poll for their answer. Provide context.title (a specific, non-empty one-line headline \u2014 this is what the user sees first, and what shows on the ring for a call) and context.description (an array of standalone, non-empty detail chunks the user can selectively ask you to expand). Set `urgency`: 'inbox' (default) drops it silently in their inbox; 'call' rings their phone now as a voice call \u2014 use 'call' only when you genuinely need them in the moment (blocked/waiting, time-sensitive), not for routine FYIs. Plus optional options (answerable choices; each may carry a sandboxed `html` or an `image` preview for a visual 'pick one' \u2014 e.g. show layout/UI alternatives) and visuals. Use `select` to control how the user answers options: 'one' (default) = pick a single option; 'many' = multi-select, user checks any subset \u2192 answer arrives as {kind:'multi', optionIds:[...]}; 'rank' = select and order, user taps options in preferred order \u2192 answer arrives as {kind:'ranked', optionIds:[...]} (ordered by choice). If a reply comes back as {kind:'clarify', chunks:[...]}, the user wants more detail on those chunks \u2014 respond via notify_user with the SAME threadId and an expanded description. Pass `threadId` from a prior notify_user result or an await_reply reply to continue that conversation thread; omit it to start a new one.",
|
|
275
281
|
inputSchema: zodToJsonSchema(NotifyRequestSchema, { target: "openApi3" })
|
|
276
282
|
},
|
|
277
283
|
{
|