@paigy/mcp 0.18.0 → 0.20.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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AGENT_NAME
3
- } from "./chunk-RMTTO6BI.js";
3
+ } from "./chunk-VWQQ3VJF.js";
4
4
 
5
5
  // src/clients.ts
6
6
  import { execFile } from "child_process";
@@ -329,8 +329,9 @@ var InboxItemSchema = z.object({
329
329
  * ("call back after lunch") — shown so they can see the commitment was captured. */
330
330
  intents: z.array(IntentSchema).optional(),
331
331
  visuals: z.array(VisualSchema).optional(),
332
- agent: z.string(),
333
- nickname: z.string(),
332
+ /** The connected agent's name (the single pairing name — user-typed, or the
333
+ * agent's suggestion, or a default silly name). */
334
+ name: z.string(),
334
335
  /** The pairing's assigned voice (#462); absent = the default voice. */
335
336
  voice: VoiceKeySchema.optional(),
336
337
  repo: z.string().optional(),
@@ -438,8 +439,8 @@ var HistoryItemSchema = z.object({
438
439
  /** 'user' = a request you sent; 'agent' = a notification an agent sent you. */
439
440
  initiator: z.enum(["user", "agent"]),
440
441
  title: z.string(),
441
- /** The agent on the other end (nickname). */
442
- agent: z.string(),
442
+ /** The agent on the other end (its name). */
443
+ name: z.string(),
443
444
  createdAt: z.string(),
444
445
  /** When the agent fetched your request (user→agent only). */
445
446
  agentAckedAt: z.string().nullable(),
@@ -449,9 +450,12 @@ var HistoryItemSchema = z.object({
449
450
  var ConnectionSummarySchema = z.object({
450
451
  /** The connection = the agent's token id (used to address a request). */
451
452
  id: z.string(),
452
- agent: z.string(),
453
453
  device: z.string().nullable(),
454
- nickname: z.string(),
454
+ /** The agent's display name (the single pairing name). */
455
+ name: z.string(),
456
+ /** For a managed connection, the provider key (e.g. "cma") that agentOrigin maps to a
457
+ * label; null for a local connection. Sourced from the token's provider, not the name. */
458
+ provider: z.string().nullable(),
455
459
  /** The pairing's assigned voice (#462); null = the default voice. */
456
460
  voice: VoiceKeySchema.nullable(),
457
461
  createdAt: z.string().datetime(),
@@ -502,8 +506,7 @@ var DeliveryConfigSchema = z.object({
502
506
  realtime: z.object({ url: z.string(), anonKey: z.string() }).nullable()
503
507
  });
504
508
  var StatusSchema = z.object({
505
- agent: z.string(),
506
- nickname: z.string(),
509
+ name: z.string(),
507
510
  sessionMode: z.enum(["default", "all_calls", "silent"]),
508
511
  /** A phone is registered for push/ring (any push token on the account). */
509
512
  phone: z.boolean()
@@ -550,14 +553,6 @@ var WakeNudgeSchema = z.object({
550
553
  notificationId: z.string().optional(),
551
554
  threadId: z.string()
552
555
  });
553
- var DeviceAgentTokenSchema = z.object({
554
- token: z.string(),
555
- deviceId: z.string(),
556
- agentName: z.string(),
557
- /** User-chosen session label; defaults to `<agent> <device>`. */
558
- nickname: z.string(),
559
- createdAt: z.string().datetime()
560
- });
561
556
  var PairingStatusSchema = z.enum(["pending", "approved", "denied", "expired"]);
562
557
  var PairingRevealSchema = z.object({
563
558
  x25519: z.string(),
@@ -565,6 +560,12 @@ var PairingRevealSchema = z.object({
565
560
  nonce: z.string()
566
561
  });
567
562
  var DeviceCodeRequestSchema = z.object({
563
+ /** The agent's suggested name for the pairing — the human sees it pre-filled at
564
+ * approval and can override. Optional; blank → a default silly name server-side. */
565
+ suggestedName: z.string().optional(),
566
+ /** Legacy alias for suggestedName (older MCPs sent `agent`). Accepted for
567
+ * back-compat; `suggestedName` wins when both are present. ponytail: drop once no
568
+ * pre-`name` MCP is in the wild. */
568
569
  agent: z.union([z.string(), z.object({ name: z.string().optional() })]).optional(),
569
570
  device: z.string().optional(),
570
571
  proto: z.string().optional(),
@@ -582,7 +583,9 @@ var DeviceCodeSchema = z.object({
582
583
  });
583
584
  var DeviceInfoSchema = z.object({
584
585
  code: z.string(),
585
- agent: z.string(),
586
+ /** The agent's suggested name (from /device/code) — shown on the approval screen,
587
+ * pre-filling the name field the human can edit. */
588
+ name: z.string(),
586
589
  device: z.string().nullable(),
587
590
  status: PairingStatusSchema,
588
591
  proto: z.string().nullable().optional(),
@@ -605,8 +608,9 @@ var DeviceTokenRequestSchema = z.object({
605
608
  });
606
609
  var DeviceTokenSchema = z.object({
607
610
  access_token: z.string(),
608
- nickname: z.string(),
609
- agent: z.string(),
611
+ /** The pairing's single name (user-typed at approval, the agent's suggestion, or
612
+ * a default silly name). */
613
+ name: z.string(),
610
614
  device: z.string().nullable(),
611
615
  phone_reveal: PairingRevealSchema.nullable().optional(),
612
616
  // present once the phone reveals
@@ -2618,8 +2618,9 @@ var InboxItemSchema = z.object({
2618
2618
  * ("call back after lunch") — shown so they can see the commitment was captured. */
2619
2619
  intents: z.array(IntentSchema).optional(),
2620
2620
  visuals: z.array(VisualSchema).optional(),
2621
- agent: z.string(),
2622
- nickname: z.string(),
2621
+ /** The connected agent's name (the single pairing name — user-typed, or the
2622
+ * agent's suggestion, or a default silly name). */
2623
+ name: z.string(),
2623
2624
  /** The pairing's assigned voice (#462); absent = the default voice. */
2624
2625
  voice: VoiceKeySchema.optional(),
2625
2626
  repo: z.string().optional(),
@@ -2727,8 +2728,8 @@ var HistoryItemSchema = z.object({
2727
2728
  /** 'user' = a request you sent; 'agent' = a notification an agent sent you. */
2728
2729
  initiator: z.enum(["user", "agent"]),
2729
2730
  title: z.string(),
2730
- /** The agent on the other end (nickname). */
2731
- agent: z.string(),
2731
+ /** The agent on the other end (its name). */
2732
+ name: z.string(),
2732
2733
  createdAt: z.string(),
2733
2734
  /** When the agent fetched your request (user→agent only). */
2734
2735
  agentAckedAt: z.string().nullable(),
@@ -2738,9 +2739,12 @@ var HistoryItemSchema = z.object({
2738
2739
  var ConnectionSummarySchema = z.object({
2739
2740
  /** The connection = the agent's token id (used to address a request). */
2740
2741
  id: z.string(),
2741
- agent: z.string(),
2742
2742
  device: z.string().nullable(),
2743
- nickname: z.string(),
2743
+ /** The agent's display name (the single pairing name). */
2744
+ name: z.string(),
2745
+ /** For a managed connection, the provider key (e.g. "cma") that agentOrigin maps to a
2746
+ * label; null for a local connection. Sourced from the token's provider, not the name. */
2747
+ provider: z.string().nullable(),
2744
2748
  /** The pairing's assigned voice (#462); null = the default voice. */
2745
2749
  voice: VoiceKeySchema.nullable(),
2746
2750
  createdAt: z.string().datetime(),
@@ -2789,8 +2793,7 @@ var DeliveryConfigSchema = z.object({
2789
2793
  realtime: z.object({ url: z.string(), anonKey: z.string() }).nullable()
2790
2794
  });
2791
2795
  var StatusSchema = z.object({
2792
- agent: z.string(),
2793
- nickname: z.string(),
2796
+ name: z.string(),
2794
2797
  sessionMode: z.enum(["default", "all_calls", "silent"]),
2795
2798
  /** A phone is registered for push/ring (any push token on the account). */
2796
2799
  phone: z.boolean()
@@ -2837,14 +2840,6 @@ var WakeNudgeSchema = z.object({
2837
2840
  notificationId: z.string().optional(),
2838
2841
  threadId: z.string()
2839
2842
  });
2840
- var DeviceAgentTokenSchema = z.object({
2841
- token: z.string(),
2842
- deviceId: z.string(),
2843
- agentName: z.string(),
2844
- /** User-chosen session label; defaults to `<agent> <device>`. */
2845
- nickname: z.string(),
2846
- createdAt: z.string().datetime()
2847
- });
2848
2843
  var PairingStatusSchema = z.enum(["pending", "approved", "denied", "expired"]);
2849
2844
  var PairingRevealSchema = z.object({
2850
2845
  x25519: z.string(),
@@ -2852,6 +2847,12 @@ var PairingRevealSchema = z.object({
2852
2847
  nonce: z.string()
2853
2848
  });
2854
2849
  var DeviceCodeRequestSchema = z.object({
2850
+ /** The agent's suggested name for the pairing — the human sees it pre-filled at
2851
+ * approval and can override. Optional; blank → a default silly name server-side. */
2852
+ suggestedName: z.string().optional(),
2853
+ /** Legacy alias for suggestedName (older MCPs sent `agent`). Accepted for
2854
+ * back-compat; `suggestedName` wins when both are present. ponytail: drop once no
2855
+ * pre-`name` MCP is in the wild. */
2855
2856
  agent: z.union([z.string(), z.object({ name: z.string().optional() })]).optional(),
2856
2857
  device: z.string().optional(),
2857
2858
  proto: z.string().optional(),
@@ -2869,7 +2870,9 @@ var DeviceCodeSchema = z.object({
2869
2870
  });
2870
2871
  var DeviceInfoSchema = z.object({
2871
2872
  code: z.string(),
2872
- agent: z.string(),
2873
+ /** The agent's suggested name (from /device/code) — shown on the approval screen,
2874
+ * pre-filling the name field the human can edit. */
2875
+ name: z.string(),
2873
2876
  device: z.string().nullable(),
2874
2877
  status: PairingStatusSchema,
2875
2878
  proto: z.string().nullable().optional(),
@@ -2892,8 +2895,9 @@ var DeviceTokenRequestSchema = z.object({
2892
2895
  });
2893
2896
  var DeviceTokenSchema = z.object({
2894
2897
  access_token: z.string(),
2895
- nickname: z.string(),
2896
- agent: z.string(),
2898
+ /** The pairing's single name (user-typed at approval, the agent's suggestion, or
2899
+ * a default silly name). */
2900
+ name: z.string(),
2897
2901
  device: z.string().nullable(),
2898
2902
  phone_reveal: PairingRevealSchema.nullable().optional(),
2899
2903
  // present once the phone reveals
@@ -3266,11 +3270,13 @@ async function revokeToken(token) {
3266
3270
  });
3267
3271
  return res.ok;
3268
3272
  }
3269
- async function requestCode(agent2 = AGENT_NAME, e2ee) {
3273
+ async function requestCode(suggestedName = AGENT_NAME, e2ee) {
3270
3274
  const res = await reach(`${BACKEND_URL}/api/device/code`, {
3271
3275
  method: "POST",
3272
3276
  headers: { "content-type": "application/json" },
3273
- body: JSON.stringify(e2ee ? { agent: agent2, proto: e2ee.proto, commitment: e2ee.commitment } : { agent: agent2 })
3277
+ body: JSON.stringify(
3278
+ e2ee ? { suggestedName, proto: e2ee.proto, commitment: e2ee.commitment } : { suggestedName }
3279
+ )
3274
3280
  });
3275
3281
  if (!res.ok) throw new Error(`/api/device/code failed: ${res.status} ${await res.text()}`);
3276
3282
  return await res.json();
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  HandoffSchema
4
- } from "./chunk-DSWZOBK5.js";
4
+ } from "./chunk-SLWESECN.js";
5
5
  import {
6
6
  PAIGY_TOOL_IDS,
7
7
  autoConfigureClients,
8
8
  claudeInstallHint,
9
9
  enablePaigyTools
10
- } from "./chunk-HAG2VWKB.js";
10
+ } from "./chunk-HO3OJHRA.js";
11
11
  import {
12
12
  clearSurface,
13
13
  writeSurface
@@ -38,7 +38,7 @@ import {
38
38
  sleep,
39
39
  startE2ee,
40
40
  submitNotification
41
- } from "./chunk-RMTTO6BI.js";
41
+ } from "./chunk-VWQQ3VJF.js";
42
42
 
43
43
  // src/index.ts
44
44
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -189,8 +189,7 @@ function pairedResult(token, sas, note, e2ee) {
189
189
  clearSurface();
190
190
  const base = {
191
191
  status: "paired",
192
- nickname: token.nickname,
193
- agent: token.agent,
192
+ name: token.name,
194
193
  device: token.device
195
194
  };
196
195
  if (sas) {
@@ -322,7 +321,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
322
321
  },
323
322
  {
324
323
  name: "handoff",
325
- description: "Deposit your working context for a SUCCESSOR agent \u2014 what you did, what's left, links, gotchas \u2014 as one note on a thread ({ title, notes[] }). This does NOT ring the user or enter their inbox: it's context, not a question. The successor reads it back with get_thread. Pass `target` (a sibling connection's token id or agent nickname, SAME account only) to hand off DIRECTLY to that agent \u2014 the note is dispatched to it as a request it picks up. Omit `target` to leave the thread for the user to hand off to an agent themselves in the app. Pass `threadId` to land the handoff on an existing conversation; omit it to mint a fresh thread. Returns { threadId }.",
324
+ description: "Deposit your working context for a SUCCESSOR agent \u2014 what you did, what's left, links, gotchas \u2014 as one note on a thread ({ title, notes[] }). This does NOT ring the user or enter their inbox: it's context, not a question. The successor reads it back with get_thread. Pass `target` (a sibling connection's token id or agent name, SAME account only) to hand off DIRECTLY to that agent \u2014 the note is dispatched to it as a request it picks up. Omit `target` to leave the thread for the user to hand off to an agent themselves in the app. Pass `threadId` to land the handoff on an existing conversation; omit it to mint a fresh thread. Returns { threadId }.",
326
325
  inputSchema: json(HandoffSchema)
327
326
  }
328
327
  ]
@@ -335,13 +334,32 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
335
334
  throw e;
336
335
  }
337
336
  });
337
+ var CLIENT_LABELS = {
338
+ "claude-code": "Claude Code",
339
+ "claude-ai": "Claude",
340
+ cursor: "Cursor",
341
+ "cursor-vscode": "Cursor",
342
+ windsurf: "Windsurf",
343
+ cline: "Cline",
344
+ "roo-cline": "Roo Code",
345
+ continue: "Continue",
346
+ vscode: "VS Code",
347
+ "visual studio code": "VS Code",
348
+ zed: "Zed"
349
+ };
350
+ function suggestedAgentName() {
351
+ if (process.env.PAIGY_AGENT) return process.env.PAIGY_AGENT;
352
+ const raw = server.getClientVersion?.()?.name;
353
+ if (!raw) return void 0;
354
+ return CLIENT_LABELS[raw.toLowerCase()] ?? raw.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
355
+ }
338
356
  async function handleTool(request) {
339
357
  switch (request.params.name) {
340
358
  case "pair": {
341
359
  const { device_code } = PairSchema.parse(request.params.arguments ?? {});
342
360
  if (!device_code) {
343
361
  const { keyFile, offer } = startE2ee();
344
- const code = await requestCode(void 0, offer);
362
+ const code = await requestCode(suggestedAgentName(), offer);
345
363
  saveKeyFile({ ...keyFile, userCode: code.user_code });
346
364
  writeSurface("pairing code", code.user_code, code.expires_in);
347
365
  startBackgroundPair(code.device_code, code.expires_in * 1e3);
package/dist/listen.js CHANGED
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  WAKE_EVENT,
4
4
  wakeChannel
5
- } from "./chunk-DSWZOBK5.js";
5
+ } from "./chunk-SLWESECN.js";
6
6
  import {
7
7
  checkReplies,
8
8
  registerDelivery
9
- } from "./chunk-RMTTO6BI.js";
9
+ } from "./chunk-VWQQ3VJF.js";
10
10
 
11
11
  // src/listen.ts
12
12
  import { createClient } from "@supabase/supabase-js";
package/dist/onboard.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  autoConfigureClients,
4
4
  claudeInstallHint,
5
5
  openBrowser
6
- } from "./chunk-HAG2VWKB.js";
6
+ } from "./chunk-HO3OJHRA.js";
7
7
  import {
8
8
  AGENT_NAME,
9
9
  TOKEN_PATH,
@@ -11,7 +11,7 @@ import {
11
11
  requestCode,
12
12
  saveToken,
13
13
  sleep
14
- } from "./chunk-RMTTO6BI.js";
14
+ } from "./chunk-VWQQ3VJF.js";
15
15
 
16
16
  // src/onboard.ts
17
17
  async function main() {
@@ -39,9 +39,8 @@ Paigy MCP onboarding (agent: "${AGENT_NAME}")
39
39
 
40
40
  Paired! Token saved to ${TOKEN_PATH} (mode 0600).`);
41
41
  console.log("Treat this token like a password \u2014 it grants account access. Never log, echo, or commit it.");
42
- console.log(` Nickname : ${token.nickname}`);
43
- console.log(` Agent : ${token.agent}`);
44
- console.log(` Device : ${token.device ?? "(none)"}
42
+ console.log(` Name : ${token.name}`);
43
+ console.log(` Device : ${token.device ?? "(none)"}
45
44
  `);
46
45
  const registered = autoConfigureClients();
47
46
  if (registered.length) {
@@ -6,7 +6,7 @@ import {
6
6
  BACKEND_URL,
7
7
  reach,
8
8
  readToken
9
- } from "./chunk-RMTTO6BI.js";
9
+ } from "./chunk-VWQQ3VJF.js";
10
10
 
11
11
  // src/statusline.ts
12
12
  import { mkdirSync, readFileSync, realpathSync, writeFileSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paigy/mcp",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
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",
@@ -36,8 +36,8 @@
36
36
  "tsup": "^8.3.5",
37
37
  "typescript": "^5.7.2",
38
38
  "vitest": "^2.1.8",
39
- "@paigy/schema": "0.0.0",
40
39
  "@paigy/sdk": "0.1.0",
40
+ "@paigy/schema": "0.0.0",
41
41
  "@paigy/crypto": "0.0.0"
42
42
  },
43
43
  "scripts": {