@paigy/mcp 0.14.1 → 0.14.2

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.
Files changed (2) hide show
  1. package/dist/index.js +34 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -156,18 +156,22 @@ function pairedResult(token, sas, note, e2ee) {
156
156
  function awaitingConfirmResult(sas, device_code) {
157
157
  writeSurface("verify code", sas, 600);
158
158
  return {
159
- content: [{
160
- type: "text",
161
- text: JSON.stringify({
162
- status: "awaiting_confirmation",
163
- e2ee: true,
164
- sas,
165
- device_code,
166
- user_message: `# ${sas}`,
167
- verify_message: `Send \`user_message\` to the user VERBATIM as your entire next message \u2014 it is pre-composed; do not rewrite or wrap it. YOUR NEXT MESSAGE TO THE USER MUST BE EXACTLY THIS CODE AND NOTHING ELSE, displayed large (a markdown heading): ${sas} \u2014 it is the verification code they must compare and type on their phone. Do not wrap it in explanation; every extra sentence buries it. This code REPLACES any earlier one (older pairing attempts are now stale).`,
168
- message: "No token is issued until the user confirms the code match on their phone (E2EE account). After sending the bare code, call pair again with this device_code to keep waiting \u2014 the token arrives only after they confirm."
169
- })
170
- }]
159
+ content: [
160
+ { type: "text", text: `VERIFY CODE: ${sas}
161
+ Check it matches the code on the phone, then type it there to confirm.` },
162
+ {
163
+ type: "text",
164
+ text: JSON.stringify({
165
+ status: "awaiting_confirmation",
166
+ e2ee: true,
167
+ sas,
168
+ device_code,
169
+ user_message: `# ${sas}`,
170
+ verify_message: `STOP HERE: end your turn now with \`user_message\` (the bare code) as your entire reply \u2014 do NOT call pair again in this same turn, or the code text is dropped before the user sees it. This is the verification code they compare + type on their phone; it REPLACES any earlier one. Poll for their confirmation by calling pair with this device_code on your NEXT turn.`,
171
+ message: "No token is issued until the user confirms the code match on their phone (E2EE account)."
172
+ })
173
+ }
174
+ ]
171
175
  };
172
176
  }
173
177
  var server = new Server(
@@ -181,7 +185,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
181
185
  tools: [
182
186
  {
183
187
  name: "pair",
184
- description: "Pair this agent with the user's Paigy account (one-time) \u2014 required before notify_user/await_reply work. Two steps: (1) call with NO args to start; it attempts to open the user's browser and returns { verification_uri_complete, user_code, device_code, qr }. That open attempt can silently fail in headless/remote environments (no browser to open) \u2014 always show the user verification_uri_complete AND user_code regardless of whether it opened, so they can go there manually and enter the code themselves if needed; ask them to approve. `qr` is a terminal-renderable ASCII QR code of the same link \u2014 a scan-to-pair alternative to opening a browser at all, handy when the user's phone is right there; print it verbatim in a fenced code block. (2) call again passing that device_code to finish; it waits for approval and saves the token. If it returns { status:'pending' }, the user hasn't approved yet \u2014 call again with the same device_code to keep waiting.",
188
+ description: "Pair this agent with the user's Paigy account (one-time) \u2014 required before notify_user/await_reply work. It does NOT open a browser; the user enters the code in the Paigy app (or scans `qr`). Step 1: call with NO args \u2014 returns { user_code, device_code, qr, user_message }. Then END YOUR TURN immediately, replying with `user_message` (the bare code) as your ENTIRE message \u2014 do NOT chain the step-2 call in the same turn, or the code text is dropped before the user ever sees it (this is the #1 pairing bug). Step 2 (a SEPARATE later turn, after the user says they've entered it): call with that device_code to poll for approval; on { status:'pending' } call again to keep waiting; on { status:'awaiting_confirmation' } (E2EE) show the bare `user_message` verify code and end the turn again, polling on the next. The leading text block of every result already states the code plainly, so it shows even if you emit no prose.",
185
189
  inputSchema: json(PairSchema)
186
190
  },
187
191
  {
@@ -229,21 +233,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
229
233
  qr.addData(code.verification_uri_complete);
230
234
  qr.make();
231
235
  return {
232
- content: [{
233
- type: "text",
234
- text: JSON.stringify({
235
- status: "awaiting_approval",
236
- verification_uri_complete: code.verification_uri_complete,
237
- user_code: code.user_code,
238
- device_code: code.device_code,
239
- expires_in: code.expires_in,
240
- qr: qr.createASCII(1, 2),
241
- user_message: `# ${code.user_code}
236
+ content: [
237
+ { type: "text", text: `PAIRING CODE: ${code.user_code}
238
+ Enter it in the Paigy app: Inbox \u2192 Add a new agent.` },
239
+ {
240
+ type: "text",
241
+ text: JSON.stringify({
242
+ status: "awaiting_approval",
243
+ verification_uri_complete: code.verification_uri_complete,
244
+ user_code: code.user_code,
245
+ device_code: code.device_code,
246
+ expires_in: code.expires_in,
247
+ qr: qr.createASCII(1, 2),
248
+ user_message: `# ${code.user_code}
242
249
 
243
250
  Enter it in the Paigy app (Inbox \u2192 Add a new agent).`,
244
- message: `Send \`user_message\` to the user VERBATIM as your entire next message \u2014 it is pre-composed; do not rewrite or wrap it. YOUR NEXT MESSAGE TO THE USER MUST BE EXACTLY THIS CODE displayed large (a markdown heading): ${code.user_code} \u2014 plus ONE short line: enter it in the Paigy app (Inbox \u2192 Add a new agent). No other prose. Do NOT open a browser for the user. If their phone is handy they may prefer scanning \`qr\` (print it verbatim in a fenced code block on request). Then immediately call pair again with this device_code \u2014 it polls for the approval.`
245
- })
246
- }]
251
+ message: `STOP HERE: end your turn now with \`user_message\` as your entire reply (the bare code, nothing else) \u2014 do NOT call pair again in this same turn, or the code text is dropped before the user sees it. Do NOT open a browser. Poll for approval by calling pair with this device_code on your NEXT turn, after you've shown the code. The user may prefer scanning \`qr\` (print it verbatim in a fenced code block on request).`
252
+ })
253
+ }
254
+ ]
247
255
  };
248
256
  }
249
257
  let kf = readKeyFile();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paigy/mcp",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "description": "Paigy MCP server — a voice inbox for your AI agents. Lets an agent notify a user and await their reply.",
5
5
  "license": "MIT",
6
6
  "type": "module",