@beeper/desktop-mcp 4.2.3 → 4.7.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.
Files changed (384) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +18 -199
  3. package/auth.d.mts +6 -0
  4. package/auth.d.mts.map +1 -0
  5. package/auth.d.ts +6 -0
  6. package/auth.d.ts.map +1 -0
  7. package/auth.js +37 -0
  8. package/auth.js.map +1 -0
  9. package/auth.mjs +32 -0
  10. package/auth.mjs.map +1 -0
  11. package/code-tool-types.d.mts +7 -7
  12. package/code-tool-types.d.mts.map +1 -1
  13. package/code-tool-types.d.ts +7 -7
  14. package/code-tool-types.d.ts.map +1 -1
  15. package/code-tool-worker.d.mts.map +1 -1
  16. package/code-tool-worker.d.ts.map +1 -1
  17. package/code-tool-worker.js +103 -19
  18. package/code-tool-worker.js.map +1 -1
  19. package/code-tool-worker.mjs +103 -19
  20. package/code-tool-worker.mjs.map +1 -1
  21. package/code-tool.d.mts +12 -3
  22. package/code-tool.d.mts.map +1 -1
  23. package/code-tool.d.ts +12 -3
  24. package/code-tool.d.ts.map +1 -1
  25. package/code-tool.js +276 -95
  26. package/code-tool.js.map +1 -1
  27. package/code-tool.mjs +273 -95
  28. package/code-tool.mjs.map +1 -1
  29. package/docs-search-tool.d.mts +22 -9
  30. package/docs-search-tool.d.mts.map +1 -1
  31. package/docs-search-tool.d.ts +22 -9
  32. package/docs-search-tool.d.ts.map +1 -1
  33. package/docs-search-tool.js +37 -6
  34. package/docs-search-tool.js.map +1 -1
  35. package/docs-search-tool.mjs +37 -6
  36. package/docs-search-tool.mjs.map +1 -1
  37. package/http.d.mts +6 -9
  38. package/http.d.mts.map +1 -1
  39. package/http.d.ts +6 -9
  40. package/http.d.ts.map +1 -1
  41. package/http.js +81 -47
  42. package/http.js.map +1 -1
  43. package/http.mjs +80 -43
  44. package/http.mjs.map +1 -1
  45. package/index.js +19 -50
  46. package/index.js.map +1 -1
  47. package/index.mjs +19 -50
  48. package/index.mjs.map +1 -1
  49. package/instructions.d.mts +2 -0
  50. package/instructions.d.mts.map +1 -0
  51. package/instructions.d.ts +2 -0
  52. package/instructions.d.ts.map +1 -0
  53. package/instructions.js +48 -0
  54. package/instructions.js.map +1 -0
  55. package/instructions.mjs +45 -0
  56. package/instructions.mjs.map +1 -0
  57. package/logger.d.mts +7 -0
  58. package/logger.d.mts.map +1 -0
  59. package/logger.d.ts +7 -0
  60. package/logger.d.ts.map +1 -0
  61. package/logger.js +29 -0
  62. package/logger.js.map +1 -0
  63. package/logger.mjs +22 -0
  64. package/logger.mjs.map +1 -0
  65. package/methods.d.mts +10 -0
  66. package/methods.d.mts.map +1 -0
  67. package/methods.d.ts +10 -0
  68. package/methods.d.ts.map +1 -0
  69. package/methods.js +203 -0
  70. package/methods.js.map +1 -0
  71. package/methods.mjs +199 -0
  72. package/methods.mjs.map +1 -0
  73. package/options.d.mts +9 -9
  74. package/options.d.mts.map +1 -1
  75. package/options.d.ts +9 -9
  76. package/options.d.ts.map +1 -1
  77. package/options.js +54 -359
  78. package/options.js.map +1 -1
  79. package/options.mjs +54 -359
  80. package/options.mjs.map +1 -1
  81. package/package.json +68 -72
  82. package/server.d.mts +10 -16
  83. package/server.d.mts.map +1 -1
  84. package/server.d.ts +10 -16
  85. package/server.d.ts.map +1 -1
  86. package/server.js +82 -101
  87. package/server.js.map +1 -1
  88. package/server.mjs +81 -96
  89. package/server.mjs.map +1 -1
  90. package/src/auth.ts +42 -0
  91. package/src/code-tool-types.ts +8 -5
  92. package/src/code-tool-worker.ts +118 -34
  93. package/src/code-tool.ts +359 -118
  94. package/src/docs-search-tool.ts +59 -7
  95. package/src/http.ts +99 -50
  96. package/src/index.ts +22 -63
  97. package/src/instructions.ts +67 -0
  98. package/src/logger.ts +28 -0
  99. package/src/methods.ts +224 -0
  100. package/src/options.ts +72 -384
  101. package/src/server.ts +94 -117
  102. package/src/stdio.ts +6 -5
  103. package/src/{tools/types.ts → types.ts} +25 -5
  104. package/src/util.ts +25 -0
  105. package/stdio.d.mts +1 -1
  106. package/stdio.d.mts.map +1 -1
  107. package/stdio.d.ts +1 -1
  108. package/stdio.d.ts.map +1 -1
  109. package/stdio.js +5 -4
  110. package/stdio.js.map +1 -1
  111. package/stdio.mjs +5 -4
  112. package/stdio.mjs.map +1 -1
  113. package/{tools/types.d.mts → types.d.mts} +10 -2
  114. package/types.d.mts.map +1 -0
  115. package/{tools/types.d.ts → types.d.ts} +10 -2
  116. package/types.d.ts.map +1 -0
  117. package/{tools/types.js → types.js} +12 -0
  118. package/types.js.map +1 -0
  119. package/{tools/types.mjs → types.mjs} +11 -0
  120. package/types.mjs.map +1 -0
  121. package/util.d.mts +4 -0
  122. package/util.d.mts.map +1 -0
  123. package/util.d.ts +4 -0
  124. package/util.d.ts.map +1 -0
  125. package/util.js +30 -0
  126. package/util.js.map +1 -0
  127. package/util.mjs +24 -0
  128. package/util.mjs.map +1 -0
  129. package/compat.d.mts +0 -58
  130. package/compat.d.mts.map +0 -1
  131. package/compat.d.ts +0 -58
  132. package/compat.d.ts.map +0 -1
  133. package/compat.js +0 -387
  134. package/compat.js.map +0 -1
  135. package/compat.mjs +0 -378
  136. package/compat.mjs.map +0 -1
  137. package/dynamic-tools.d.mts +0 -12
  138. package/dynamic-tools.d.mts.map +0 -1
  139. package/dynamic-tools.d.ts +0 -12
  140. package/dynamic-tools.d.ts.map +0 -1
  141. package/dynamic-tools.js +0 -135
  142. package/dynamic-tools.js.map +0 -1
  143. package/dynamic-tools.mjs +0 -132
  144. package/dynamic-tools.mjs.map +0 -1
  145. package/filtering.d.mts +0 -2
  146. package/filtering.d.mts.map +0 -1
  147. package/filtering.d.ts +0 -2
  148. package/filtering.d.ts.map +0 -1
  149. package/filtering.js +0 -20
  150. package/filtering.js.map +0 -1
  151. package/filtering.mjs +0 -13
  152. package/filtering.mjs.map +0 -1
  153. package/handlers/get-accounts.d.mts +0 -3
  154. package/handlers/get-accounts.d.mts.map +0 -1
  155. package/handlers/get-accounts.d.ts +0 -3
  156. package/handlers/get-accounts.d.ts.map +0 -1
  157. package/handlers/get-accounts.js +0 -32
  158. package/handlers/get-accounts.js.map +0 -1
  159. package/handlers/get-accounts.mjs +0 -28
  160. package/handlers/get-accounts.mjs.map +0 -1
  161. package/handlers/get-chat.d.mts +0 -3
  162. package/handlers/get-chat.d.mts.map +0 -1
  163. package/handlers/get-chat.d.ts +0 -3
  164. package/handlers/get-chat.d.ts.map +0 -1
  165. package/handlers/get-chat.js +0 -20
  166. package/handlers/get-chat.js.map +0 -1
  167. package/handlers/get-chat.mjs +0 -16
  168. package/handlers/get-chat.mjs.map +0 -1
  169. package/handlers/index.d.mts +0 -3
  170. package/handlers/index.d.mts.map +0 -1
  171. package/handlers/index.d.ts +0 -3
  172. package/handlers/index.d.ts.map +0 -1
  173. package/handlers/index.js +0 -30
  174. package/handlers/index.js.map +0 -1
  175. package/handlers/index.mjs +0 -27
  176. package/handlers/index.mjs.map +0 -1
  177. package/handlers/list-chats.d.mts +0 -3
  178. package/handlers/list-chats.d.mts.map +0 -1
  179. package/handlers/list-chats.d.ts +0 -3
  180. package/handlers/list-chats.d.ts.map +0 -1
  181. package/handlers/list-chats.js +0 -46
  182. package/handlers/list-chats.js.map +0 -1
  183. package/handlers/list-chats.mjs +0 -42
  184. package/handlers/list-chats.mjs.map +0 -1
  185. package/handlers/list-messages.d.mts +0 -3
  186. package/handlers/list-messages.d.mts.map +0 -1
  187. package/handlers/list-messages.d.ts +0 -3
  188. package/handlers/list-messages.d.ts.map +0 -1
  189. package/handlers/list-messages.js +0 -34
  190. package/handlers/list-messages.js.map +0 -1
  191. package/handlers/list-messages.mjs +0 -30
  192. package/handlers/list-messages.mjs.map +0 -1
  193. package/handlers/open-app.d.mts +0 -3
  194. package/handlers/open-app.d.mts.map +0 -1
  195. package/handlers/open-app.d.ts +0 -3
  196. package/handlers/open-app.d.ts.map +0 -1
  197. package/handlers/open-app.js +0 -26
  198. package/handlers/open-app.js.map +0 -1
  199. package/handlers/open-app.mjs +0 -22
  200. package/handlers/open-app.mjs.map +0 -1
  201. package/handlers/search-chats.d.mts +0 -3
  202. package/handlers/search-chats.d.mts.map +0 -1
  203. package/handlers/search-chats.d.ts +0 -3
  204. package/handlers/search-chats.d.ts.map +0 -1
  205. package/handlers/search-chats.js +0 -38
  206. package/handlers/search-chats.js.map +0 -1
  207. package/handlers/search-chats.mjs +0 -34
  208. package/handlers/search-chats.mjs.map +0 -1
  209. package/handlers/search-messages.d.mts +0 -3
  210. package/handlers/search-messages.d.mts.map +0 -1
  211. package/handlers/search-messages.d.ts +0 -3
  212. package/handlers/search-messages.d.ts.map +0 -1
  213. package/handlers/search-messages.js +0 -11
  214. package/handlers/search-messages.js.map +0 -1
  215. package/handlers/search-messages.mjs +0 -7
  216. package/handlers/search-messages.mjs.map +0 -1
  217. package/handlers/search.d.mts +0 -3
  218. package/handlers/search.d.mts.map +0 -1
  219. package/handlers/search.d.ts +0 -3
  220. package/handlers/search.d.ts.map +0 -1
  221. package/handlers/search.js +0 -29
  222. package/handlers/search.js.map +0 -1
  223. package/handlers/search.mjs +0 -25
  224. package/handlers/search.mjs.map +0 -1
  225. package/handlers/send-message.d.mts +0 -3
  226. package/handlers/send-message.d.mts.map +0 -1
  227. package/handlers/send-message.d.ts +0 -3
  228. package/handlers/send-message.d.ts.map +0 -1
  229. package/handlers/send-message.js +0 -20
  230. package/handlers/send-message.js.map +0 -1
  231. package/handlers/send-message.mjs +0 -16
  232. package/handlers/send-message.mjs.map +0 -1
  233. package/handlers/utils.d.mts +0 -29
  234. package/handlers/utils.d.mts.map +0 -1
  235. package/handlers/utils.d.ts +0 -29
  236. package/handlers/utils.d.ts.map +0 -1
  237. package/handlers/utils.js +0 -296
  238. package/handlers/utils.js.map +0 -1
  239. package/handlers/utils.mjs +0 -282
  240. package/handlers/utils.mjs.map +0 -1
  241. package/headers.d.mts +0 -4
  242. package/headers.d.mts.map +0 -1
  243. package/headers.d.ts +0 -4
  244. package/headers.d.ts.map +0 -1
  245. package/headers.js +0 -22
  246. package/headers.js.map +0 -1
  247. package/headers.mjs +0 -18
  248. package/headers.mjs.map +0 -1
  249. package/src/compat.ts +0 -483
  250. package/src/dynamic-tools.ts +0 -159
  251. package/src/filtering.ts +0 -14
  252. package/src/handlers/get-accounts.ts +0 -28
  253. package/src/handlers/get-chat.ts +0 -18
  254. package/src/handlers/index.ts +0 -29
  255. package/src/handlers/list-chats.ts +0 -47
  256. package/src/handlers/list-messages.ts +0 -33
  257. package/src/handlers/open-app.ts +0 -20
  258. package/src/handlers/search-chats.ts +0 -39
  259. package/src/handlers/search-messages.ts +0 -8
  260. package/src/handlers/search.ts +0 -24
  261. package/src/handlers/send-message.ts +0 -17
  262. package/src/handlers/utils.ts +0 -381
  263. package/src/headers.ts +0 -23
  264. package/src/tools/accounts/get-accounts.ts +0 -34
  265. package/src/tools/chats/archive-chat.ts +0 -43
  266. package/src/tools/chats/get-chat.ts +0 -45
  267. package/src/tools/chats/reminders/clear-chat-reminder.ts +0 -41
  268. package/src/tools/chats/reminders/set-chat-reminder.ts +0 -54
  269. package/src/tools/chats/search-chats.ts +0 -104
  270. package/src/tools/index.ts +0 -92
  271. package/src/tools/messages/list-messages.ts +0 -51
  272. package/src/tools/messages/search-messages.ts +0 -123
  273. package/src/tools/messages/send-message.ts +0 -47
  274. package/src/tools/top-level/focus-app.ts +0 -52
  275. package/src/tools/top-level/search.ts +0 -41
  276. package/src/tools.ts +0 -1
  277. package/tools/accounts/get-accounts.d.mts +0 -45
  278. package/tools/accounts/get-accounts.d.mts.map +0 -1
  279. package/tools/accounts/get-accounts.d.ts +0 -45
  280. package/tools/accounts/get-accounts.d.ts.map +0 -1
  281. package/tools/accounts/get-accounts.js +0 -31
  282. package/tools/accounts/get-accounts.js.map +0 -1
  283. package/tools/accounts/get-accounts.mjs +0 -27
  284. package/tools/accounts/get-accounts.mjs.map +0 -1
  285. package/tools/chats/archive-chat.d.mts +0 -45
  286. package/tools/chats/archive-chat.d.mts.map +0 -1
  287. package/tools/chats/archive-chat.d.ts +0 -45
  288. package/tools/chats/archive-chat.d.ts.map +0 -1
  289. package/tools/chats/archive-chat.js +0 -40
  290. package/tools/chats/archive-chat.js.map +0 -1
  291. package/tools/chats/archive-chat.mjs +0 -36
  292. package/tools/chats/archive-chat.mjs.map +0 -1
  293. package/tools/chats/get-chat.d.mts +0 -45
  294. package/tools/chats/get-chat.d.mts.map +0 -1
  295. package/tools/chats/get-chat.d.ts +0 -45
  296. package/tools/chats/get-chat.d.ts.map +0 -1
  297. package/tools/chats/get-chat.js +0 -41
  298. package/tools/chats/get-chat.js.map +0 -1
  299. package/tools/chats/get-chat.mjs +0 -37
  300. package/tools/chats/get-chat.mjs.map +0 -1
  301. package/tools/chats/reminders/clear-chat-reminder.d.mts +0 -45
  302. package/tools/chats/reminders/clear-chat-reminder.d.mts.map +0 -1
  303. package/tools/chats/reminders/clear-chat-reminder.d.ts +0 -45
  304. package/tools/chats/reminders/clear-chat-reminder.d.ts.map +0 -1
  305. package/tools/chats/reminders/clear-chat-reminder.js +0 -38
  306. package/tools/chats/reminders/clear-chat-reminder.js.map +0 -1
  307. package/tools/chats/reminders/clear-chat-reminder.mjs +0 -34
  308. package/tools/chats/reminders/clear-chat-reminder.mjs.map +0 -1
  309. package/tools/chats/reminders/set-chat-reminder.d.mts +0 -45
  310. package/tools/chats/reminders/set-chat-reminder.d.mts.map +0 -1
  311. package/tools/chats/reminders/set-chat-reminder.d.ts +0 -45
  312. package/tools/chats/reminders/set-chat-reminder.d.ts.map +0 -1
  313. package/tools/chats/reminders/set-chat-reminder.js +0 -51
  314. package/tools/chats/reminders/set-chat-reminder.js.map +0 -1
  315. package/tools/chats/reminders/set-chat-reminder.mjs +0 -47
  316. package/tools/chats/reminders/set-chat-reminder.mjs.map +0 -1
  317. package/tools/chats/search-chats.d.mts +0 -45
  318. package/tools/chats/search-chats.d.mts.map +0 -1
  319. package/tools/chats/search-chats.d.ts +0 -45
  320. package/tools/chats/search-chats.d.ts.map +0 -1
  321. package/tools/chats/search-chats.js +0 -92
  322. package/tools/chats/search-chats.js.map +0 -1
  323. package/tools/chats/search-chats.mjs +0 -88
  324. package/tools/chats/search-chats.mjs.map +0 -1
  325. package/tools/index.d.mts +0 -10
  326. package/tools/index.d.mts.map +0 -1
  327. package/tools/index.d.ts +0 -10
  328. package/tools/index.d.ts.map +0 -1
  329. package/tools/index.js +0 -76
  330. package/tools/index.js.map +0 -1
  331. package/tools/index.mjs +0 -69
  332. package/tools/index.mjs.map +0 -1
  333. package/tools/messages/list-messages.d.mts +0 -45
  334. package/tools/messages/list-messages.d.mts.map +0 -1
  335. package/tools/messages/list-messages.d.ts +0 -45
  336. package/tools/messages/list-messages.d.ts.map +0 -1
  337. package/tools/messages/list-messages.js +0 -47
  338. package/tools/messages/list-messages.js.map +0 -1
  339. package/tools/messages/list-messages.mjs +0 -43
  340. package/tools/messages/list-messages.mjs.map +0 -1
  341. package/tools/messages/search-messages.d.mts +0 -45
  342. package/tools/messages/search-messages.d.mts.map +0 -1
  343. package/tools/messages/search-messages.d.ts +0 -45
  344. package/tools/messages/search-messages.d.ts.map +0 -1
  345. package/tools/messages/search-messages.js +0 -110
  346. package/tools/messages/search-messages.js.map +0 -1
  347. package/tools/messages/search-messages.mjs +0 -106
  348. package/tools/messages/search-messages.mjs.map +0 -1
  349. package/tools/messages/send-message.d.mts +0 -45
  350. package/tools/messages/send-message.d.mts.map +0 -1
  351. package/tools/messages/send-message.d.ts +0 -45
  352. package/tools/messages/send-message.d.ts.map +0 -1
  353. package/tools/messages/send-message.js +0 -43
  354. package/tools/messages/send-message.js.map +0 -1
  355. package/tools/messages/send-message.mjs +0 -39
  356. package/tools/messages/send-message.mjs.map +0 -1
  357. package/tools/top-level/focus-app.d.mts +0 -45
  358. package/tools/top-level/focus-app.d.mts.map +0 -1
  359. package/tools/top-level/focus-app.d.ts +0 -45
  360. package/tools/top-level/focus-app.d.ts.map +0 -1
  361. package/tools/top-level/focus-app.js +0 -47
  362. package/tools/top-level/focus-app.js.map +0 -1
  363. package/tools/top-level/focus-app.mjs +0 -43
  364. package/tools/top-level/focus-app.mjs.map +0 -1
  365. package/tools/top-level/search.d.mts +0 -45
  366. package/tools/top-level/search.d.mts.map +0 -1
  367. package/tools/top-level/search.d.ts +0 -45
  368. package/tools/top-level/search.d.ts.map +0 -1
  369. package/tools/top-level/search.js +0 -37
  370. package/tools/top-level/search.js.map +0 -1
  371. package/tools/top-level/search.mjs +0 -33
  372. package/tools/top-level/search.mjs.map +0 -1
  373. package/tools/types.d.mts.map +0 -1
  374. package/tools/types.d.ts.map +0 -1
  375. package/tools/types.js.map +0 -1
  376. package/tools/types.mjs.map +0 -1
  377. package/tools.d.mts +0 -2
  378. package/tools.d.mts.map +0 -1
  379. package/tools.d.ts +0 -2
  380. package/tools.d.ts.map +0 -1
  381. package/tools.js +0 -18
  382. package/tools.js.map +0 -1
  383. package/tools.mjs +0 -2
  384. package/tools.mjs.map +0 -1
@@ -1,28 +0,0 @@
1
- import type { HandlerFunction } from '../tools/types';
2
- import { asMarkdownContentResult } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client) => {
5
- const accounts = await client.accounts.list();
6
- if (!accounts || accounts.length === 0)
7
- throw new Error('No accounts found. This should never happen, please contact help@beeper.com.');
8
- const lines: string[] = [];
9
- lines.push('# Accounts');
10
- for (const acc of accounts) {
11
- if (!acc.user) {
12
- lines.push(`\n## ${acc.network}`);
13
- lines.push(`**Account ID**: \`${acc.accountID}\``);
14
- lines.push('**User**: Unknown');
15
- continue;
16
- }
17
-
18
- const name = acc.user.fullName || acc.user.username || acc.user.id;
19
- lines.push(`\n## ${acc.network}`);
20
- lines.push(`**Account ID**: \`${acc.accountID}\``);
21
- lines.push(`**User**: ${name}`);
22
- if (acc.user.email) lines.push(`**Email**: ${acc.user.email}`);
23
- if (acc.user.phoneNumber) lines.push(`**Phone**: ${acc.user.phoneNumber}`);
24
- }
25
- lines.push('\n# Using this information\n');
26
- lines.push('- Pass accountIDs to narrow chat/message queries when known.');
27
- return asMarkdownContentResult(lines);
28
- };
@@ -1,18 +0,0 @@
1
- import type { HandlerFunction } from '../tools/types';
2
- import { asMarkdownContentResult, formatChatToMarkdown } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client, args) => {
5
- const { chatID, ...queryParams } = args as any;
6
- const chat = await client.chats.retrieve(chatID, queryParams);
7
-
8
- const lines: string[] = [];
9
- if (!chat) {
10
- lines.push('Chat not found.');
11
- return asMarkdownContentResult(lines);
12
- }
13
- lines.push(formatChatToMarkdown(chat, undefined));
14
- lines.push('\n# Using this information\n');
15
- lines.push('- Use search_messages to find specific content in this chat.');
16
- lines.push('- Link the "open" link to the user to allow them to view the chat in Beeper Desktop.');
17
- return asMarkdownContentResult(lines);
18
- };
@@ -1,29 +0,0 @@
1
- import type { Endpoint, HandlerFunction } from '../tools';
2
-
3
- import { handler as get_accounts } from './get-accounts';
4
- import { handler as open_in_app } from './open-app';
5
- import { handler as search } from './search';
6
- import { handler as get_chat } from './get-chat';
7
- import { handler as search_chats } from './search-chats';
8
- import { handler as search_messages } from './search-messages';
9
- import { handler as send_message } from './send-message';
10
-
11
- const HANDLER_OVERRIDES: Record<string, HandlerFunction> = {
12
- get_accounts,
13
- open_in_app,
14
- focus_app: open_in_app,
15
- search,
16
- get_chat,
17
- search_chats,
18
- search_messages,
19
- send_message,
20
- };
21
-
22
- export function mapEndpoint(endpoint: Endpoint): Endpoint {
23
- const handler = HANDLER_OVERRIDES[endpoint.tool.name];
24
- if (!handler) return endpoint;
25
- return {
26
- ...endpoint,
27
- handler,
28
- };
29
- }
@@ -1,47 +0,0 @@
1
- import type { HandlerFunction } from '../tools/types';
2
- import { asMarkdownContentResult, formatChatToMarkdown } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client, args) => {
5
- const body = args as any;
6
- const output = await client.chats.search(body);
7
-
8
- const lines: string[] = [];
9
- lines.push('# Chats');
10
-
11
- const items = output.items || [];
12
- const hasMore = !!output.hasMore;
13
-
14
- if (hasMore) {
15
- lines.push(`\nShowing ${items.length} chats (more available)`);
16
- if (output.oldestCursor) {
17
- lines.push(`Next page (older): cursor='${output.oldestCursor}', direction='before'`);
18
- }
19
- if (output.newestCursor) {
20
- lines.push(`Previous page (newer): cursor='${output.newestCursor}', direction='after'`);
21
- }
22
- } else if (items.length > 0) {
23
- lines.push(`\nShowing ${items.length} chat${items.length === 1 ? '' : 's'}`);
24
- }
25
-
26
- if (items.length === 0) {
27
- lines.push('\nNo chats found.');
28
- } else {
29
- for (const chatWithPreview of items) {
30
- lines.push(formatChatToMarkdown(chatWithPreview, undefined));
31
- const preview = (chatWithPreview as any).preview;
32
- if (preview) {
33
- lines.push(`**Last message**: ${preview.text || '(no text)'}`);
34
- if (preview.senderName) {
35
- lines.push(`**From**: ${preview.senderName}`);
36
- }
37
- lines.push(`**Timestamp**: ${preview.timestamp}`);
38
- }
39
- }
40
- }
41
- lines.push('\n# Using this information\n');
42
- lines.push(
43
- '- Pass the "chatID" to get_chat or search_messages for details about a chat, or send_message to send a message to a chat.',
44
- );
45
- lines.push('- Link the "open" link to the user to allow them to view the chat in Beeper Desktop.');
46
- return asMarkdownContentResult(lines);
47
- };
@@ -1,33 +0,0 @@
1
- import { asTextContentResult, type HandlerFunction } from '../tools/types';
2
- import { mapMessagesToText } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client, args) => {
5
- const body = args as any;
6
- const output = await client.messages.search(body);
7
-
8
- const lines: string[] = [];
9
- lines.push('# Messages');
10
-
11
- const items = (output as any).items || [];
12
- const hasMore = !!(output as any).hasMore;
13
-
14
- if (hasMore) {
15
- lines.push(`\nShowing ${items.length} messages (more available)`);
16
- if ((output as any).oldestCursor) {
17
- lines.push(`Next page (older): cursor='${(output as any).oldestCursor}', direction='before'`);
18
- }
19
- if ((output as any).newestCursor) {
20
- lines.push(`Previous page (newer): cursor='${(output as any).newestCursor}', direction='after'`);
21
- }
22
- } else if (items.length > 0) {
23
- lines.push(`\nShowing ${items.length} message${items.length === 1 ? '' : 's'}`);
24
- }
25
-
26
- if (items.length === 0) {
27
- lines.push('\nNo messages found.');
28
- } else {
29
- lines.push(mapMessagesToText(output as any, body, undefined));
30
- }
31
-
32
- return asTextContentResult(lines.join('\n'));
33
- };
@@ -1,20 +0,0 @@
1
- import { asTextContentResult, type HandlerFunction } from '../tools/types';
2
-
3
- export const handler: HandlerFunction = async (client, args) => {
4
- const body = args as any;
5
- const output = await client.focus(body);
6
-
7
- const lines: string[] = [];
8
- if (output.success) {
9
- lines.push('Beeper was opened.');
10
- if (body?.chatID) {
11
- const chatRef = String(body.chatID);
12
- lines.push(`Focused chat: ${chatRef}`);
13
- }
14
- if (body?.draftText) lines.push(`Draft text populated: ${body.draftText}`);
15
- if (body?.draftAttachmentPath) lines.push(`Draft attachment populated: ${body.draftAttachmentPath}`);
16
- } else {
17
- lines.push('Failed to open Beeper.');
18
- }
19
- return asTextContentResult(lines.join('\n'));
20
- };
@@ -1,39 +0,0 @@
1
- import type { HandlerFunction } from '../tools/types';
2
- import { asMarkdownContentResult, formatChatToMarkdown } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client, args) => {
5
- const body = args as any;
6
- const output = await client.chats.search(body);
7
-
8
- const lines: string[] = [];
9
- lines.push('# Chats');
10
-
11
- const items = output.items || [];
12
- const hasMore = !!output.hasMore;
13
-
14
- if (hasMore) {
15
- lines.push(`\nFound ${items.length}+ chats (showing ${items.length})`);
16
- if (output.oldestCursor) {
17
- lines.push(`Next page (older): cursor='${output.oldestCursor}', direction='before'`);
18
- }
19
- if (output.newestCursor) {
20
- lines.push(`Previous page (newer): cursor='${output.newestCursor}', direction='after'`);
21
- }
22
- } else if (items.length > 0) {
23
- lines.push(`\nFound ${items.length} chat${items.length === 1 ? '' : 's'}`);
24
- }
25
-
26
- if (items.length === 0) {
27
- lines.push('\nNo chats found.');
28
- } else {
29
- for (const chat of items) {
30
- lines.push(formatChatToMarkdown(chat, undefined));
31
- }
32
- }
33
- lines.push('\n# Using this information\n');
34
- lines.push(
35
- '- Pass the "chatID" to get_chat or search_messages for details about a chat, or send_message to send a message to a chat.',
36
- );
37
- lines.push('- Link the "open" link to the user to allow them to view the chat in Beeper Desktop.');
38
- return asMarkdownContentResult(lines);
39
- };
@@ -1,8 +0,0 @@
1
- import type { HandlerFunction } from '../tools/types';
2
- import { mapMessagesToText, asMarkdownContentResult } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client, args) => {
5
- const body = args as any;
6
- const output = await client.messages.search(body);
7
- return asMarkdownContentResult(mapMessagesToText(output, body, undefined));
8
- };
@@ -1,24 +0,0 @@
1
- import type { HandlerFunction } from '../tools/types';
2
- import { asMarkdownContentResult, formatChatToMarkdown, mapMessagesToText } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client, args) => {
5
- const body = args as any;
6
- const output = await client.search(body);
7
-
8
- const lines: string[] = [];
9
- if (body?.query) lines.push(`Query: "${body.query}"`);
10
- const results = output?.results;
11
- if (results?.chats?.length) {
12
- lines.push('\n# Chats');
13
- for (const chat of results.chats) lines.push(formatChatToMarkdown(chat, undefined));
14
- }
15
- if (results?.in_groups?.length) {
16
- lines.push('\n# In Groups');
17
- for (const chat of results.in_groups) lines.push(formatChatToMarkdown(chat, undefined));
18
- }
19
- if (results?.messages?.items?.length) {
20
- lines.push('\n# Messages');
21
- lines.push(mapMessagesToText(results.messages as any, body, undefined));
22
- }
23
- return asMarkdownContentResult(lines);
24
- };
@@ -1,17 +0,0 @@
1
- import type { HandlerFunction } from '../tools/types';
2
- import { asMarkdownContentResult, createOpenLink } from './utils';
3
-
4
- export const handler: HandlerFunction = async (client, args) => {
5
- const { chatID, ...body } = args as any;
6
- const output = await client.messages.send(chatID, body);
7
-
8
- const lines: string[] = [];
9
- if (output.pendingMessageID) {
10
- const deeplink = createOpenLink('', chatID ?? '');
11
- if (deeplink) lines.push(`**Open the chat in Beeper**: ${deeplink}`);
12
- } else {
13
- lines.push('Failed to send message.');
14
- }
15
-
16
- return asMarkdownContentResult(lines);
17
- };
@@ -1,381 +0,0 @@
1
- import {
2
- differenceInMilliseconds,
3
- differenceInDays,
4
- endOfDay,
5
- format,
6
- isToday,
7
- isYesterday,
8
- isSameYear,
9
- parse,
10
- } from 'date-fns';
11
- import type * as Shared from '@beeper/desktop-api/resources/shared';
12
- import type * as ChatsAPI from '@beeper/desktop-api/resources/chats/chats';
13
- import { ToolCallResult } from '../tools/types';
14
-
15
- const MILLIS_IN_WEEK = 86400000 * 7;
16
-
17
- type Message = Shared.Message;
18
- type Chat = ChatsAPI.Chat;
19
- type User = Shared.User;
20
- type MessageReaction = NonNullable<Message['reactions']>[number];
21
-
22
- export const formatRelativeDate = (date: Date) => {
23
- const timeDifference = differenceInMilliseconds(endOfDay(new Date()), date);
24
-
25
- if (isToday(date)) return 'Today';
26
- if (isYesterday(date)) return 'Yesterday';
27
-
28
- return new Intl.DateTimeFormat(
29
- 'default',
30
- timeDifference < MILLIS_IN_WEEK ?
31
- {
32
- weekday: 'long',
33
- }
34
- : isSameYear(date, new Date()) ?
35
- {
36
- weekday: 'short',
37
- month: 'short',
38
- day: 'numeric',
39
- }
40
- : {
41
- year: 'numeric',
42
- month: 'short',
43
- day: 'numeric',
44
- },
45
- ).format(date);
46
- };
47
-
48
- export const formatBytes = (bytes: number, decimals = 0) => {
49
- if (bytes === 0) return '0 B';
50
-
51
- const k = 1024;
52
- const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
53
- const i = Math.floor(Math.log(bytes) / Math.log(k));
54
-
55
- return `${Math.floor(parseFloat((bytes / k ** i).toFixed(decimals)))}${sizes[i]}`;
56
- };
57
-
58
- const skinToneRegex = /\uD83C[\uDFFB-\uDFFF]/g;
59
- const removeSkinTone = (emojiString: string): string => emojiString.replace(skinToneRegex, '');
60
-
61
- export function groupReactions(reactions: MessageReaction[]): { [key: string]: MessageReaction[] } {
62
- const map: { [key: string]: MessageReaction[] } = {};
63
- reactions.forEach((reaction) => {
64
- if (!reaction.reactionKey) return;
65
- const key = removeSkinTone(reaction.reactionKey);
66
- map[key] ||= [];
67
- map[key].push(reaction);
68
- });
69
- return map;
70
- }
71
-
72
- export const getParticipantName = (participant: User, preferFirstName?: boolean): string =>
73
- participant.fullName && preferFirstName ?
74
- participant.fullName.split(' ')[0]!
75
- : participant.fullName ||
76
- participant.username ||
77
- participant.email ||
78
- participant.phoneNumber ||
79
- participant.id;
80
-
81
- export const createOpenLink = (baseURL: string, localChatIDOrChatID: string, messageKey?: string) =>
82
- `${baseURL}/open/${encodeURIComponent(localChatIDOrChatID)}${messageKey ? `/${messageKey}` : ''}`;
83
-
84
- export const formatParticipantsToMarkdown = (participants: User[] | undefined, limit = 3): string => {
85
- if (!participants || participants.length === 0) return '';
86
-
87
- const names = participants
88
- .slice(0, limit)
89
- .map((p) => p.fullName || p.username || p.id)
90
- .filter(Boolean);
91
-
92
- if (participants.length > limit) {
93
- const othersCount = participants.length - limit;
94
- names.push(`& ${othersCount} other${othersCount === 1 ? '' : 's'}`);
95
- }
96
-
97
- return names.join(', ');
98
- };
99
-
100
- export const formatReactionsToMarkdown = (
101
- reactions: Message['reactions'],
102
- participants?: Map<string, User>,
103
- ): string => {
104
- if (!reactions || reactions.length === 0) return '';
105
-
106
- const reactionMap = groupReactions(reactions);
107
- const reactionParts: string[] = [];
108
- for (const [reactionKey, reactionList] of Object.entries(reactionMap)) {
109
- const count = reactionList.length;
110
- const reactorNames = reactionList
111
- .slice(0, 5)
112
- .map((r) => {
113
- if (!r.participantID) return null;
114
- const participant = participants?.get(r.participantID);
115
- return participant ? getParticipantName(participant) : r.participantID;
116
- })
117
- .filter(Boolean);
118
-
119
- let reactorInfo = '';
120
- if (reactorNames.length > 0) {
121
- if (count > 5) {
122
- const othersCount = count - 5;
123
- reactorInfo = ` (${reactorNames.join(', ')} & ${othersCount} other${othersCount === 1 ? '' : 's'})`;
124
- } else {
125
- reactorInfo = ` (${reactorNames.join(', ')})`;
126
- }
127
- }
128
-
129
- reactionParts.push(`${reactionKey} ${count}${reactorInfo}`);
130
- }
131
-
132
- return reactionParts.length > 0 ? ` [${reactionParts.join(' ')}]` : '';
133
- };
134
-
135
- export const formatAttachmentToMarkdown = (attachment: Shared.Attachment | undefined): string => {
136
- if (!attachment) return '';
137
-
138
- const typeEmoji =
139
- {
140
- img: 'šŸ–¼',
141
- video: 'šŸŽ„',
142
- audio: 'šŸŽµ',
143
- unknown: 'šŸ“Ž',
144
- }[attachment.type] || 'šŸ“Ž';
145
-
146
- const fileName = attachment.fileName || 'file';
147
- const url = attachment.srcURL || '';
148
- const hasBothDimensions =
149
- typeof attachment.size?.width === 'number' && typeof attachment.size?.height === 'number';
150
-
151
- const metaInfo: string[] = [];
152
- if (attachment.fileSize) {
153
- metaInfo.push(formatBytes(attachment.fileSize));
154
- }
155
- if (hasBothDimensions) {
156
- metaInfo.push(`${attachment.size!.width}x${attachment.size!.height}`);
157
- }
158
-
159
- const metaString = metaInfo.length > 0 ? ` (${metaInfo.join(', ')})` : '';
160
-
161
- return `\n${typeEmoji} [${fileName}](${url})${metaString}`;
162
- };
163
-
164
- export const formatChatToMarkdown = (chat: Chat, baseURL: string | undefined): string => {
165
- const openURL = baseURL ? createOpenLink(baseURL, chat.localChatID ?? chat.id) : undefined;
166
- const title = openURL ? `[${chat.title}](${openURL})` : chat.title;
167
- const participantList =
168
- chat.participants?.items ? formatParticipantsToMarkdown(chat.participants.items, 3) : '';
169
- const participantInfo = participantList ? ` with ${participantList}` : '';
170
- const lines: string[] = [];
171
- lines.push(`\n## ${title} (chatID: ${chat.localChatID})`);
172
- let chatLine = `Chat on ${chat.network}${participantInfo}.`;
173
- if (typeof chat.unreadCount === 'number' && chat.unreadCount > 0) {
174
- chatLine += ` It has ${chat.unreadCount} unread message${chat.unreadCount === 1 ? '' : 's'}.`;
175
- }
176
- lines.push(chatLine);
177
- lines.push(`**Type**: ${chat.type}`);
178
- if (chat.lastActivity) lines.push(`**Last Activity**: ${chat.lastActivity}`);
179
- const status: string[] = [];
180
- if (chat.isArchived) status.push('archived');
181
- if (chat.isMuted) status.push('muted');
182
- if (chat.isPinned) status.push('pinned');
183
- if (status.length > 0) lines.push(`This chat is ${status.join(', ')}.`);
184
- return lines.join('\n');
185
- };
186
-
187
- const parseLocalDateKey = (key: string): Date => {
188
- const parsed = parse(key, 'yyyy-MM-dd', new Date());
189
- if (isNaN(parsed.getTime())) {
190
- throw new Error(`Invalid date key: ${key}`);
191
- }
192
- return parsed;
193
- };
194
-
195
- interface MessagesResponse {
196
- items: Message[];
197
- chats: Record<string, Chat>;
198
- hasMore?: boolean;
199
- oldestCursor?: string;
200
- newestCursor?: string;
201
- }
202
-
203
- export const mapMessagesToText = (
204
- output: Shared.MessagesCursorSearch,
205
- input?: {
206
- query?: string;
207
- sender?: string;
208
- mediaTypes?: string[];
209
- },
210
- ctx?: { apiBaseURL?: string; maxTextLength?: number },
211
- ) => {
212
- const { items, hasMore } = output;
213
- const chats = (output as any)?.body?.chats ?? {};
214
-
215
- const messageCount = items.length;
216
- const chatCount = Object.keys(chats).length;
217
-
218
- // Determine if search filters would cause gaps in timeline
219
- // Gaps occur when filtering by: query text, sender, or media types
220
- // Gaps do NOT occur when only filtering by: chatIDs, accountIDs, chatType, or date ranges
221
- const hasGapCausingFilters =
222
- input && (input.query || input.sender || (input.mediaTypes && input.mediaTypes.length > 0));
223
-
224
- const paginationInfo: string[] = [];
225
- if (messageCount === 0) {
226
- if (!chats || chatCount === 0) {
227
- paginationInfo.push('No matching chats found');
228
- } else {
229
- paginationInfo.push(`No messages found in ${chatCount} chat${chatCount === 1 ? '' : 's'}`);
230
- }
231
- } else if (hasMore) {
232
- paginationInfo.push(
233
- `Found ${messageCount}+ messages across ${chatCount} chat${
234
- chatCount === 1 ? '' : 's'
235
- } (showing ${messageCount})`,
236
- );
237
- if (output.oldestCursor) {
238
- paginationInfo.push(`Next page (older): cursor='${output.oldestCursor}', direction='before'`);
239
- }
240
- if (output.newestCursor) {
241
- paginationInfo.push(`Previous page (newer): cursor='${output.newestCursor}', direction='after'`);
242
- }
243
- } else {
244
- paginationInfo.push(
245
- `Found ${messageCount} message${messageCount === 1 ? '' : 's'} across ${chatCount} chat${
246
- chatCount === 1 ? '' : 's'
247
- } (complete)`,
248
- );
249
- }
250
-
251
- if (hasGapCausingFilters && messageCount > 0) {
252
- paginationInfo.push('āš ļø Filtered results: only showing messages matching your search criteria.');
253
- }
254
-
255
- const messagesByChat = new Map<string, typeof items>();
256
- for (const message of items) {
257
- const chatMessages = messagesByChat.get(message.chatID) || [];
258
- chatMessages.push(message);
259
- messagesByChat.set(message.chatID, chatMessages);
260
- }
261
-
262
- const chatSummaries: string[] = [];
263
- for (const [chatID, messages] of messagesByChat) {
264
- const chat = chats[chatID];
265
- if (chat) {
266
- chatSummaries.push(`# ${chat.title} [${messages.length} message${messages.length === 1 ? '' : 's'}]`);
267
- }
268
- }
269
-
270
- const headerLines = [...paginationInfo, '', ...chatSummaries];
271
-
272
- const summary = headerLines.join('\n');
273
-
274
- const chatSections: string[] = [];
275
-
276
- for (const [chatID, messages] of messagesByChat) {
277
- const chat = chats[chatID];
278
- if (!chat) continue;
279
-
280
- const participantList =
281
- chat.participants?.items ? formatParticipantsToMarkdown(chat.participants.items, 3) : '';
282
- const participantInfo = participantList ? ` with ${participantList}` : '';
283
- const openURL = ctx?.apiBaseURL ? createOpenLink(ctx.apiBaseURL, chat.localChatID ?? chat.id) : undefined;
284
- const title = openURL ? `[${chat.title}](${openURL})` : chat.title;
285
- chatSections.push(`# ${title} (chatID: ${chat.localChatID})`);
286
- chatSections.push(`Chat on ${chat.network}${participantInfo}.`);
287
- chatSections.push('');
288
-
289
- const messagesByDate = new Map<string, Message[]>();
290
- for (const message of messages) {
291
- const dateKey = format(new Date(message.timestamp), 'yyyy-MM-dd');
292
- const dateMessages = messagesByDate.get(dateKey) || [];
293
- dateMessages.push(message);
294
- messagesByDate.set(dateKey, dateMessages);
295
- }
296
-
297
- const sortedDates = Array.from(messagesByDate.keys()).sort();
298
-
299
- const participantMap =
300
- chat?.participants?.items ?
301
- new Map<string, User>(chat.participants.items.map((p: User) => [p.id, p]))
302
- : undefined;
303
-
304
- for (let i = 0; i < sortedDates.length; i++) {
305
- const dateKey = sortedDates[i]!;
306
- const dateObj = parseLocalDateKey(dateKey);
307
- const relativeTime = formatRelativeDate(dateObj);
308
- chatSections.push(`## ${relativeTime} (${dateKey})`);
309
- chatSections.push('');
310
-
311
- const dateMessages = messagesByDate.get(dateKey) || [];
312
- dateMessages.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
313
-
314
- for (const message of dateMessages) {
315
- const time = new Date(message.timestamp);
316
- const timeStr = format(time, 'HH:mm');
317
-
318
- const baseSenderName = message.senderName || message.senderID;
319
- const senderName = message.isSender ? `${baseSenderName} (You)` : baseSenderName;
320
-
321
- const maxTextLength = ctx?.maxTextLength ?? 1000;
322
- let text = message.text || '';
323
- if (text && text.length > maxTextLength) {
324
- const remainingChars = text.length - maxTextLength;
325
- text = text.substring(0, maxTextLength) + `... [+${remainingChars} chars]`;
326
- }
327
-
328
- const attachment = message.attachments?.[0]; // Assume single attachment
329
- const attachmentChatID = chat.localChatID ?? chat.id;
330
- const attachmentLink =
331
- attachment && attachmentChatID ?
332
- `\nšŸ“Ž [${attachment.fileName || 'attachment'}](beeper-mcp://attachments/${attachmentChatID}/${
333
- message.id
334
- }/0)`
335
- : '';
336
- const reactionsStr = formatReactionsToMarkdown(message.reactions, participantMap);
337
-
338
- const sortKeyLink =
339
- chat.localChatID ?
340
- `([open at sort key](${createOpenLink(
341
- ctx?.apiBaseURL || '',
342
- chat.localChatID,
343
- String(message.sortKey),
344
- )}))`
345
- : `(sortKey: ${message.sortKey})`;
346
- const messageStr = `**${senderName}** (${timeStr}): ${text}${attachmentLink}${reactionsStr} ${sortKeyLink}`;
347
-
348
- chatSections.push(messageStr);
349
- chatSections.push('');
350
- }
351
-
352
- // Add date gap indicator when dates are not consecutive
353
- if (i < sortedDates.length - 1) {
354
- const nextDateKey = sortedDates[i + 1]!;
355
- const currentDate = parseLocalDateKey(dateKey!);
356
- const nextDate = parseLocalDateKey(nextDateKey);
357
- const dayDiff = differenceInDays(nextDate, currentDate);
358
-
359
- // Only show gap if dates are not consecutive
360
- if (dayDiff > 1) {
361
- const gapDays = dayDiff - 1;
362
- chatSections.push(`*[... ${gapDays} day${gapDays === 1 ? '' : 's'} gap ...]*`);
363
- chatSections.push('');
364
- }
365
- }
366
- }
367
- }
368
-
369
- return [summary, '', ...chatSections].join('\n');
370
- };
371
-
372
- export function asMarkdownContentResult(text: string | string[]): ToolCallResult {
373
- return {
374
- content: [
375
- {
376
- type: 'text',
377
- text: Array.isArray(text) ? text.join('\n') : text,
378
- },
379
- ],
380
- };
381
- }
package/src/headers.ts DELETED
@@ -1,23 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { IncomingMessage } from 'node:http';
4
- import { ClientOptions } from '@beeper/desktop-api';
5
-
6
- export const parseAuthHeaders = (req: IncomingMessage): Partial<ClientOptions> => {
7
- if (req.headers.authorization) {
8
- const scheme = req.headers.authorization.split(' ')[0]!;
9
- const value = req.headers.authorization.slice(scheme.length + 1);
10
- switch (scheme) {
11
- case 'Bearer':
12
- return { accessToken: req.headers.authorization.slice('Bearer '.length) };
13
- default:
14
- throw new Error(`Unsupported authorization scheme`);
15
- }
16
- }
17
-
18
- const accessToken =
19
- Array.isArray(req.headers['x-beeper-access-token']) ?
20
- req.headers['x-beeper-access-token'][0]
21
- : req.headers['x-beeper-access-token'];
22
- return { accessToken };
23
- };