perplexity-user-mcp 0.8.36

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 (125) hide show
  1. package/README.md +192 -0
  2. package/dist/attachments.d.ts +20 -0
  3. package/dist/attachments.mjs +43 -0
  4. package/dist/checks/browser.d.ts +100 -0
  5. package/dist/checks/browser.mjs +89 -0
  6. package/dist/checks/config.d.ts +91 -0
  7. package/dist/checks/config.mjs +88 -0
  8. package/dist/checks/ide.d.ts +89 -0
  9. package/dist/checks/ide.mjs +80 -0
  10. package/dist/checks/mcp.d.ts +61 -0
  11. package/dist/checks/mcp.mjs +56 -0
  12. package/dist/checks/native-deps.d.ts +131 -0
  13. package/dist/checks/native-deps.mjs +115 -0
  14. package/dist/checks/network.d.ts +71 -0
  15. package/dist/checks/network.mjs +70 -0
  16. package/dist/checks/probe.d.ts +93 -0
  17. package/dist/checks/probe.mjs +82 -0
  18. package/dist/checks/profiles.d.ts +99 -0
  19. package/dist/checks/profiles.mjs +90 -0
  20. package/dist/checks/runtime.d.ts +89 -0
  21. package/dist/checks/runtime.mjs +90 -0
  22. package/dist/checks/vault.d.ts +101 -0
  23. package/dist/checks/vault.mjs +90 -0
  24. package/dist/chunk-3B276PGG.mjs +115 -0
  25. package/dist/chunk-4UEJOM6W.mjs +9 -0
  26. package/dist/chunk-6EP2BLTV.mjs +205 -0
  27. package/dist/chunk-6YMQVLFX.mjs +146 -0
  28. package/dist/chunk-7JL36EBH.mjs +118 -0
  29. package/dist/chunk-DPGMKSSA.mjs +57 -0
  30. package/dist/chunk-H4BUAPPO.mjs +1950 -0
  31. package/dist/chunk-HMKLWVXB.mjs +109 -0
  32. package/dist/chunk-HTUAQRKH.mjs +125 -0
  33. package/dist/chunk-HU5B4FXS.mjs +139 -0
  34. package/dist/chunk-KCXM2M4B.mjs +1006 -0
  35. package/dist/chunk-LKJMLGFP.mjs +237 -0
  36. package/dist/chunk-LZPLNZ5U.mjs +67 -0
  37. package/dist/chunk-MTDFKNXX.mjs +19 -0
  38. package/dist/chunk-OF4DMAPJ.mjs +511 -0
  39. package/dist/chunk-PE23RMXY.mjs +43 -0
  40. package/dist/chunk-Q2VY4R5F.mjs +175 -0
  41. package/dist/chunk-S5VD7WTU.mjs +2540 -0
  42. package/dist/chunk-SVPRB62V.mjs +106 -0
  43. package/dist/chunk-TQLCLE4L.mjs +345 -0
  44. package/dist/chunk-U3DGFLXZ.mjs +43 -0
  45. package/dist/chunk-X45O6YD3.mjs +688 -0
  46. package/dist/chunk-XKSWCEGI.mjs +168 -0
  47. package/dist/chunk-Z7DAACGZ.mjs +534 -0
  48. package/dist/chunk-ZQFUZPLO.mjs +257 -0
  49. package/dist/cli.d.ts +952 -0
  50. package/dist/cli.mjs +827 -0
  51. package/dist/client.d.ts +355 -0
  52. package/dist/client.mjs +27 -0
  53. package/dist/cloud-sync.d-Cqt6y18U.d.ts +42 -0
  54. package/dist/cloud-sync.d.ts +42 -0
  55. package/dist/cloud-sync.mjs +17 -0
  56. package/dist/config.d.ts +186 -0
  57. package/dist/config.mjs +54 -0
  58. package/dist/daemon/attach.d.ts +36 -0
  59. package/dist/daemon/attach.mjs +25 -0
  60. package/dist/daemon/audit.d.ts +23 -0
  61. package/dist/daemon/audit.mjs +12 -0
  62. package/dist/daemon/client-http.d.ts +42 -0
  63. package/dist/daemon/client-http.mjs +29 -0
  64. package/dist/daemon/index.d.ts +14 -0
  65. package/dist/daemon/index.mjs +110 -0
  66. package/dist/daemon/install-tunnel.d.ts +46 -0
  67. package/dist/daemon/install-tunnel.mjs +14 -0
  68. package/dist/daemon/launcher.d.ts +163 -0
  69. package/dist/daemon/launcher.mjs +50 -0
  70. package/dist/daemon/lockfile.d.ts +29 -0
  71. package/dist/daemon/lockfile.mjs +18 -0
  72. package/dist/daemon/server.d.ts +159 -0
  73. package/dist/daemon/server.mjs +20 -0
  74. package/dist/daemon/token.d.ts +17 -0
  75. package/dist/daemon/token.mjs +17 -0
  76. package/dist/daemon/tunnel-providers/index.d.ts +330 -0
  77. package/dist/daemon/tunnel-providers/index.mjs +57 -0
  78. package/dist/daemon/tunnel.d.ts +23 -0
  79. package/dist/daemon/tunnel.mjs +9 -0
  80. package/dist/doctor-report.d.ts +24 -0
  81. package/dist/doctor-report.mjs +14 -0
  82. package/dist/doctor.d-CXmUqOXX.d.ts +43 -0
  83. package/dist/doctor.d.ts +44 -0
  84. package/dist/doctor.mjs +16 -0
  85. package/dist/export.d.ts +19 -0
  86. package/dist/export.mjs +15 -0
  87. package/dist/health-check.d.ts +108 -0
  88. package/dist/health-check.mjs +92 -0
  89. package/dist/history-store.d-BzjBF2m3.d.ts +65 -0
  90. package/dist/history-store.d.ts +65 -0
  91. package/dist/history-store.mjs +48 -0
  92. package/dist/impit-login-runner.d.ts +469 -0
  93. package/dist/impit-login-runner.mjs +685 -0
  94. package/dist/index.d.ts +159 -0
  95. package/dist/index.mjs +236 -0
  96. package/dist/login-runner.d.ts +333 -0
  97. package/dist/login-runner.mjs +320 -0
  98. package/dist/logout.d.ts +28 -0
  99. package/dist/logout.mjs +45 -0
  100. package/dist/manual-login-runner.d.ts +150 -0
  101. package/dist/manual-login-runner.mjs +146 -0
  102. package/dist/native-deps-BNThFHxa.d.ts +175 -0
  103. package/dist/native-deps-YNKXITRY.mjs +139 -0
  104. package/dist/profiles.d-DqS1oZWr.d.ts +41 -0
  105. package/dist/profiles.d.ts +41 -0
  106. package/dist/profiles.mjs +33 -0
  107. package/dist/redact.d.ts +159 -0
  108. package/dist/redact.mjs +11 -0
  109. package/dist/refresh.d.ts +118 -0
  110. package/dist/refresh.mjs +21 -0
  111. package/dist/reinit-watcher.d.ts +15 -0
  112. package/dist/reinit-watcher.mjs +8 -0
  113. package/dist/session-metadata-B9aV_n5g.d.ts +148 -0
  114. package/dist/tty-prompt.d.ts +44 -0
  115. package/dist/tty-prompt.mjs +39 -0
  116. package/dist/vault.d-BtRSLZiM.d.ts +8 -0
  117. package/dist/vault.d.ts +37 -0
  118. package/dist/vault.mjs +21 -0
  119. package/dist/viewer-detect.d-HWGnyFAA.d.ts +4 -0
  120. package/dist/viewer-detect.d.ts +4 -0
  121. package/dist/viewer-detect.mjs +37 -0
  122. package/dist/viewers.d-BGCK6sw6.d.ts +10 -0
  123. package/dist/viewers.d.ts +18 -0
  124. package/dist/viewers.mjs +122 -0
  125. package/package.json +152 -0
@@ -0,0 +1,257 @@
1
+ import {
2
+ ensureDaemon
3
+ } from "./chunk-X45O6YD3.mjs";
4
+ import {
5
+ getPackageVersion
6
+ } from "./chunk-S5VD7WTU.mjs";
7
+
8
+ // src/daemon/client-http.ts
9
+ import { randomUUID } from "crypto";
10
+ import { statSync } from "fs";
11
+ import { TextDecoder } from "util";
12
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
13
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
14
+ async function exportHistoryViaDaemon(historyId, format, options = {}) {
15
+ const clientId = options.clientId ?? `daemon-export-${randomUUID()}`;
16
+ const result = await callDaemonTool(
17
+ "perplexity_export",
18
+ {
19
+ history_id: historyId,
20
+ format
21
+ },
22
+ { ...options, clientId }
23
+ );
24
+ const savedPath = extractBacktickedPath(result.text);
25
+ const bytes = statSync(savedPath).size;
26
+ return {
27
+ savedPath,
28
+ bytes,
29
+ contentType: getExportContentType(format)
30
+ };
31
+ }
32
+ async function syncCloudHistoryViaDaemon(options = {}) {
33
+ const clientId = options.clientId ?? `daemon-sync-${randomUUID()}`;
34
+ const daemon = await ensureDaemon(options);
35
+ const relay = options.onProgress ? await subscribeToToolProgress(daemon, clientId, "perplexity_sync_cloud", options.onProgress) : null;
36
+ try {
37
+ const result = await callDaemonTool(
38
+ "perplexity_sync_cloud",
39
+ options.pageSize ? { page_size: options.pageSize } : {},
40
+ // 5-minute budget covers limit=1000 (a few MB payload + 1000 upserts
41
+ // each writing a .md file). Far above the 60s SDK default which was
42
+ // firing as MCP error -32001 in 0.8.21.
43
+ { ...options, clientId, requestTimeoutMs: 5 * 60 * 1e3 }
44
+ );
45
+ await relay?.waitForPhase("done", 250).catch(() => void 0);
46
+ return parseCloudSyncResult(result.text);
47
+ } finally {
48
+ await relay?.close();
49
+ }
50
+ }
51
+ async function hydrateCloudHistoryEntryViaDaemon(historyId, options = {}) {
52
+ const clientId = options.clientId ?? `daemon-hydrate-${randomUUID()}`;
53
+ const result = await callDaemonTool(
54
+ "perplexity_hydrate_cloud_entry",
55
+ {
56
+ history_id: historyId
57
+ },
58
+ { ...options, clientId }
59
+ );
60
+ return parseHydrateResult(result.text);
61
+ }
62
+ async function callDaemonTool(name, args, options) {
63
+ const daemon = await ensureDaemon(options);
64
+ const clientId = options.clientId ?? `daemon-client-${randomUUID()}`;
65
+ const transport = new StreamableHTTPClientTransport(new URL(`${daemon.url}/mcp`), {
66
+ requestInit: {
67
+ headers: {
68
+ Authorization: `Bearer ${daemon.bearerToken}`,
69
+ "x-perplexity-client-id": clientId,
70
+ "x-perplexity-source": options.source ?? "loopback"
71
+ }
72
+ }
73
+ });
74
+ const client = new Client(
75
+ {
76
+ name: clientId,
77
+ version: getPackageVersion()
78
+ },
79
+ {
80
+ capabilities: {}
81
+ }
82
+ );
83
+ try {
84
+ await client.connect(transport);
85
+ const callToolOptions = options.requestTimeoutMs ? { timeout: options.requestTimeoutMs } : void 0;
86
+ const result = await client.callTool({ name, arguments: args }, void 0, callToolOptions);
87
+ if (result.isError) {
88
+ throw new Error(getToolText(result));
89
+ }
90
+ return { text: getToolText(result) };
91
+ } finally {
92
+ await client.close().catch(() => void 0);
93
+ await transport.close().catch(() => void 0);
94
+ }
95
+ }
96
+ async function subscribeToToolProgress(daemon, clientId, tool, onProgress) {
97
+ const controller = new AbortController();
98
+ const phaseWaiters = /* @__PURE__ */ new Map();
99
+ const seenPhases = /* @__PURE__ */ new Set();
100
+ const response = await fetch(`${daemon.url}/daemon/events`, {
101
+ method: "GET",
102
+ headers: {
103
+ Authorization: `Bearer ${daemon.bearerToken}`,
104
+ "x-perplexity-client-id": clientId
105
+ },
106
+ signal: controller.signal
107
+ });
108
+ if (!response.ok || !response.body) {
109
+ throw new Error(`Could not subscribe to daemon events (${response.status}).`);
110
+ }
111
+ const reader = response.body.getReader();
112
+ const decoder = new TextDecoder();
113
+ let buffer = "";
114
+ const drain = (async () => {
115
+ try {
116
+ while (true) {
117
+ const { done, value } = await reader.read();
118
+ if (done) {
119
+ break;
120
+ }
121
+ buffer += decoder.decode(value, { stream: true });
122
+ buffer = consumeSseFrames(buffer, (event, payload) => {
123
+ if (event !== "daemon:tool-progress") {
124
+ return;
125
+ }
126
+ if (payload?.clientId !== clientId || payload?.tool !== tool) {
127
+ return;
128
+ }
129
+ const progress = payload.progress;
130
+ seenPhases.add(progress.phase);
131
+ onProgress(progress);
132
+ const waiters = phaseWaiters.get(progress.phase);
133
+ if (!waiters?.length) {
134
+ return;
135
+ }
136
+ phaseWaiters.delete(progress.phase);
137
+ for (const resolve of waiters) {
138
+ resolve();
139
+ }
140
+ });
141
+ }
142
+ } catch (error) {
143
+ if (!controller.signal.aborted) {
144
+ throw error;
145
+ }
146
+ }
147
+ })();
148
+ return {
149
+ close: async () => {
150
+ controller.abort();
151
+ await drain.catch(() => void 0);
152
+ },
153
+ waitForPhase: async (phase, timeoutMs) => {
154
+ if (seenPhases.has(phase)) {
155
+ return;
156
+ }
157
+ await new Promise((resolve, reject) => {
158
+ let wrappedResolve;
159
+ const timer = setTimeout(() => {
160
+ const waiters2 = phaseWaiters.get(phase);
161
+ if (waiters2 && wrappedResolve) {
162
+ phaseWaiters.set(phase, waiters2.filter((candidate) => candidate !== wrappedResolve));
163
+ }
164
+ reject(new Error(`Timed out waiting for daemon progress phase '${phase}'.`));
165
+ }, timeoutMs);
166
+ wrappedResolve = () => {
167
+ clearTimeout(timer);
168
+ resolve();
169
+ };
170
+ const waiters = phaseWaiters.get(phase) ?? [];
171
+ waiters.push(wrappedResolve);
172
+ phaseWaiters.set(phase, waiters);
173
+ });
174
+ }
175
+ };
176
+ }
177
+ function consumeSseFrames(buffer, onFrame) {
178
+ while (true) {
179
+ const boundary = buffer.indexOf("\n\n");
180
+ if (boundary < 0) {
181
+ return buffer;
182
+ }
183
+ const frame = buffer.slice(0, boundary);
184
+ buffer = buffer.slice(boundary + 2);
185
+ if (!frame.trim()) {
186
+ continue;
187
+ }
188
+ let event = "message";
189
+ const dataLines = [];
190
+ for (const rawLine of frame.split(/\r?\n/)) {
191
+ if (rawLine.startsWith("event:")) {
192
+ event = rawLine.slice(6).trim();
193
+ } else if (rawLine.startsWith("data:")) {
194
+ dataLines.push(rawLine.slice(5).trim());
195
+ }
196
+ }
197
+ if (!dataLines.length) {
198
+ continue;
199
+ }
200
+ try {
201
+ onFrame(event, JSON.parse(dataLines.join("\n")));
202
+ } catch {
203
+ }
204
+ }
205
+ }
206
+ function parseCloudSyncResult(text) {
207
+ const match = text.match(/fetched=(\d+)\s+inserted=(\d+)\s+updated=(\d+)\s+skipped=(\d+)/i);
208
+ if (!match) {
209
+ throw new Error(`Could not parse cloud sync result: ${text}`);
210
+ }
211
+ return {
212
+ fetched: Number(match[1]),
213
+ inserted: Number(match[2]),
214
+ updated: Number(match[3]),
215
+ skipped: Number(match[4])
216
+ };
217
+ }
218
+ function parseHydrateResult(text) {
219
+ const match = text.match(/^Cloud hydrate ([a-z-]+):/i);
220
+ if (!match) {
221
+ throw new Error(`Could not parse cloud hydrate result: ${text}`);
222
+ }
223
+ const action = match[1];
224
+ if (action !== "hydrated" && action !== "skipped-local" && action !== "skipped-hydrated") {
225
+ throw new Error(`Unexpected cloud hydrate action '${action}'.`);
226
+ }
227
+ return { action };
228
+ }
229
+ function getToolText(result) {
230
+ const textItem = result?.content?.find?.((item) => item?.type === "text" && typeof item.text === "string");
231
+ if (typeof textItem?.text !== "string" || textItem.text.length === 0) {
232
+ throw new Error("Daemon tool response did not contain text output.");
233
+ }
234
+ return textItem.text;
235
+ }
236
+ function extractBacktickedPath(text) {
237
+ const match = text.match(/`([^`]+)`/);
238
+ if (!match?.[1]) {
239
+ throw new Error(`Could not parse saved path from daemon export response: ${text}`);
240
+ }
241
+ return match[1];
242
+ }
243
+ function getExportContentType(format) {
244
+ if (format === "markdown") {
245
+ return "text/markdown; charset=utf-8";
246
+ }
247
+ if (format === "pdf") {
248
+ return "application/pdf";
249
+ }
250
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
251
+ }
252
+
253
+ export {
254
+ exportHistoryViaDaemon,
255
+ syncCloudHistoryViaDaemon,
256
+ hydrateCloudHistoryEntryViaDaemon
257
+ };