youtube-knowledge-mcp 2.2.0 → 3.0.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.
Files changed (407) hide show
  1. package/README.md +126 -36
  2. package/dist/brain-schemas.d.ts +10 -0
  3. package/dist/brain-schemas.d.ts.map +1 -1
  4. package/dist/harvest-schemas.d.ts +75 -0
  5. package/dist/harvest-schemas.d.ts.map +1 -0
  6. package/dist/harvest-schemas.js +111 -0
  7. package/dist/harvest-schemas.js.map +1 -0
  8. package/dist/registry/brain-tools.d.ts.map +1 -1
  9. package/dist/registry/brain-tools.js +16 -0
  10. package/dist/registry/brain-tools.js.map +1 -1
  11. package/dist/registry/channel-tools.d.ts.map +1 -1
  12. package/dist/registry/channel-tools.js +16 -0
  13. package/dist/registry/channel-tools.js.map +1 -1
  14. package/dist/registry/harvest-tools.d.ts +10 -0
  15. package/dist/registry/harvest-tools.d.ts.map +1 -0
  16. package/dist/registry/harvest-tools.js +109 -0
  17. package/dist/registry/harvest-tools.js.map +1 -0
  18. package/dist/registry/health-tools.d.ts.map +1 -1
  19. package/dist/registry/health-tools.js +18 -0
  20. package/dist/registry/health-tools.js.map +1 -1
  21. package/dist/registry/index.d.ts.map +1 -1
  22. package/dist/registry/index.js +6 -0
  23. package/dist/registry/index.js.map +1 -1
  24. package/dist/registry/media-tools.d.ts.map +1 -1
  25. package/dist/registry/media-tools.js +31 -0
  26. package/dist/registry/media-tools.js.map +1 -1
  27. package/dist/registry/store-tools.d.ts +9 -0
  28. package/dist/registry/store-tools.d.ts.map +1 -0
  29. package/dist/registry/store-tools.js +59 -0
  30. package/dist/registry/store-tools.js.map +1 -0
  31. package/dist/registry/transcript-tools.d.ts +4 -1
  32. package/dist/registry/transcript-tools.d.ts.map +1 -1
  33. package/dist/registry/transcript-tools.js +20 -1
  34. package/dist/registry/transcript-tools.js.map +1 -1
  35. package/dist/registry/video-tools.d.ts.map +1 -1
  36. package/dist/registry/video-tools.js +49 -1
  37. package/dist/registry/video-tools.js.map +1 -1
  38. package/dist/registry/vision-tools.d.ts +7 -0
  39. package/dist/registry/vision-tools.d.ts.map +1 -0
  40. package/dist/registry/vision-tools.js +55 -0
  41. package/dist/registry/vision-tools.js.map +1 -0
  42. package/dist/schemas.d.ts +245 -0
  43. package/dist/schemas.d.ts.map +1 -1
  44. package/dist/schemas.js +58 -0
  45. package/dist/schemas.js.map +1 -1
  46. package/dist/thumbnail-schemas.d.ts +38 -28
  47. package/dist/thumbnail-schemas.d.ts.map +1 -1
  48. package/dist/tools/ask-brain.js +1 -1
  49. package/dist/tools/ask-brain.js.map +1 -1
  50. package/dist/tools/ask-brains.d.ts +66 -0
  51. package/dist/tools/ask-brains.d.ts.map +1 -0
  52. package/dist/tools/ask-brains.js +111 -0
  53. package/dist/tools/ask-brains.js.map +1 -0
  54. package/dist/tools/brain-info.js +1 -1
  55. package/dist/tools/brain-info.js.map +1 -1
  56. package/dist/tools/check-health.d.ts +75 -6
  57. package/dist/tools/check-health.d.ts.map +1 -1
  58. package/dist/tools/check-health.js +114 -6
  59. package/dist/tools/check-health.js.map +1 -1
  60. package/dist/tools/check-new-uploads.d.ts +55 -0
  61. package/dist/tools/check-new-uploads.d.ts.map +1 -0
  62. package/dist/tools/check-new-uploads.js +74 -0
  63. package/dist/tools/check-new-uploads.js.map +1 -0
  64. package/dist/tools/clips.d.ts +15 -0
  65. package/dist/tools/clips.d.ts.map +1 -1
  66. package/dist/tools/clips.js +5 -5
  67. package/dist/tools/clips.js.map +1 -1
  68. package/dist/tools/detect-scenes.d.ts +38 -0
  69. package/dist/tools/detect-scenes.d.ts.map +1 -0
  70. package/dist/tools/detect-scenes.js +66 -0
  71. package/dist/tools/detect-scenes.js.map +1 -0
  72. package/dist/tools/export-data.d.ts +85 -0
  73. package/dist/tools/export-data.d.ts.map +1 -0
  74. package/dist/tools/export-data.js +99 -0
  75. package/dist/tools/export-data.js.map +1 -0
  76. package/dist/tools/fetch-channel-thumbnails.d.ts +8 -8
  77. package/dist/tools/fetch-videos.d.ts +15 -4
  78. package/dist/tools/fetch-videos.d.ts.map +1 -1
  79. package/dist/tools/fetch-videos.js +63 -22
  80. package/dist/tools/fetch-videos.js.map +1 -1
  81. package/dist/tools/frames-subtitles.d.ts.map +1 -1
  82. package/dist/tools/frames-subtitles.js +16 -8
  83. package/dist/tools/frames-subtitles.js.map +1 -1
  84. package/dist/tools/frames.d.ts +73 -0
  85. package/dist/tools/frames.d.ts.map +1 -0
  86. package/dist/tools/frames.js +136 -0
  87. package/dist/tools/frames.js.map +1 -0
  88. package/dist/tools/get-channel-info.d.ts +2 -0
  89. package/dist/tools/get-channel-info.d.ts.map +1 -1
  90. package/dist/tools/get-channel-info.js +4 -0
  91. package/dist/tools/get-channel-info.js.map +1 -1
  92. package/dist/tools/get-comments.d.ts +238 -6
  93. package/dist/tools/get-comments.d.ts.map +1 -1
  94. package/dist/tools/get-comments.js +85 -21
  95. package/dist/tools/get-comments.js.map +1 -1
  96. package/dist/tools/get-coverage.d.ts +122 -0
  97. package/dist/tools/get-coverage.d.ts.map +1 -0
  98. package/dist/tools/get-coverage.js +105 -0
  99. package/dist/tools/get-coverage.js.map +1 -0
  100. package/dist/tools/get-sponsor-segments.d.ts +49 -0
  101. package/dist/tools/get-sponsor-segments.d.ts.map +1 -0
  102. package/dist/tools/get-sponsor-segments.js +61 -0
  103. package/dist/tools/get-sponsor-segments.js.map +1 -0
  104. package/dist/tools/get-thumbnail.d.ts.map +1 -1
  105. package/dist/tools/get-thumbnail.js +2 -1
  106. package/dist/tools/get-thumbnail.js.map +1 -1
  107. package/dist/tools/get-transcript.d.ts +1 -0
  108. package/dist/tools/get-transcript.d.ts.map +1 -1
  109. package/dist/tools/get-transcript.js +11 -4
  110. package/dist/tools/get-transcript.js.map +1 -1
  111. package/dist/tools/get-video-details.d.ts +118 -0
  112. package/dist/tools/get-video-details.d.ts.map +1 -0
  113. package/dist/tools/get-video-details.js +147 -0
  114. package/dist/tools/get-video-details.js.map +1 -0
  115. package/dist/tools/gif-concat.d.ts +49 -0
  116. package/dist/tools/gif-concat.d.ts.map +1 -0
  117. package/dist/tools/gif-concat.js +96 -0
  118. package/dist/tools/gif-concat.js.map +1 -0
  119. package/dist/tools/harvest-channel.d.ts +92 -0
  120. package/dist/tools/harvest-channel.d.ts.map +1 -0
  121. package/dist/tools/harvest-channel.js +62 -0
  122. package/dist/tools/harvest-channel.js.map +1 -0
  123. package/dist/tools/harvest-comments.d.ts +81 -0
  124. package/dist/tools/harvest-comments.d.ts.map +1 -0
  125. package/dist/tools/harvest-comments.js +115 -0
  126. package/dist/tools/harvest-comments.js.map +1 -0
  127. package/dist/tools/harvest-details.d.ts +84 -0
  128. package/dist/tools/harvest-details.d.ts.map +1 -0
  129. package/dist/tools/harvest-details.js +71 -0
  130. package/dist/tools/harvest-details.js.map +1 -0
  131. package/dist/tools/library.js +1 -1
  132. package/dist/tools/library.js.map +1 -1
  133. package/dist/tools/list-captions.d.ts +17 -0
  134. package/dist/tools/list-captions.d.ts.map +1 -0
  135. package/dist/tools/list-captions.js +60 -0
  136. package/dist/tools/list-captions.js.map +1 -0
  137. package/dist/tools/list-channel-playlists.d.ts +30 -0
  138. package/dist/tools/list-channel-playlists.d.ts.map +1 -0
  139. package/dist/tools/list-channel-playlists.js +44 -0
  140. package/dist/tools/list-channel-playlists.js.map +1 -0
  141. package/dist/tools/list-channel-thumbnails.d.ts +10 -10
  142. package/dist/tools/list-channel-thumbnails.js +1 -1
  143. package/dist/tools/list-channel-thumbnails.js.map +1 -1
  144. package/dist/tools/list-library.js +1 -1
  145. package/dist/tools/list-library.js.map +1 -1
  146. package/dist/tools/prune-harvest.d.ts +59 -0
  147. package/dist/tools/prune-harvest.d.ts.map +1 -0
  148. package/dist/tools/prune-harvest.js +108 -0
  149. package/dist/tools/prune-harvest.js.map +1 -0
  150. package/dist/tools/query-comments.d.ts +125 -0
  151. package/dist/tools/query-comments.d.ts.map +1 -0
  152. package/dist/tools/query-comments.js +106 -0
  153. package/dist/tools/query-comments.js.map +1 -0
  154. package/dist/tools/query-videos.d.ts +118 -0
  155. package/dist/tools/query-videos.d.ts.map +1 -0
  156. package/dist/tools/query-videos.js +97 -0
  157. package/dist/tools/query-videos.js.map +1 -0
  158. package/dist/tools/repair-store.d.ts +34 -0
  159. package/dist/tools/repair-store.d.ts.map +1 -0
  160. package/dist/tools/repair-store.js +58 -0
  161. package/dist/tools/repair-store.js.map +1 -0
  162. package/dist/tools/search-channels.d.ts +6 -0
  163. package/dist/tools/search-channels.d.ts.map +1 -1
  164. package/dist/tools/search-channels.js +5 -1
  165. package/dist/tools/search-channels.js.map +1 -1
  166. package/dist/tools/search-videos.js +1 -1
  167. package/dist/tools/search-videos.js.map +1 -1
  168. package/dist/tools/transcribe-video.d.ts +28 -0
  169. package/dist/tools/transcribe-video.d.ts.map +1 -0
  170. package/dist/tools/transcribe-video.js +52 -0
  171. package/dist/tools/transcribe-video.js.map +1 -0
  172. package/dist/utils/brain-fusion.d.ts +24 -0
  173. package/dist/utils/brain-fusion.d.ts.map +1 -0
  174. package/dist/utils/brain-fusion.js +18 -0
  175. package/dist/utils/brain-fusion.js.map +1 -0
  176. package/dist/utils/channel-playlists.d.ts +21 -0
  177. package/dist/utils/channel-playlists.d.ts.map +1 -0
  178. package/dist/utils/channel-playlists.js +56 -0
  179. package/dist/utils/channel-playlists.js.map +1 -0
  180. package/dist/utils/clips.d.ts.map +1 -1
  181. package/dist/utils/clips.js +3 -17
  182. package/dist/utils/clips.js.map +1 -1
  183. package/dist/utils/comment-store.d.ts +71 -0
  184. package/dist/utils/comment-store.d.ts.map +1 -0
  185. package/dist/utils/comment-store.js +129 -0
  186. package/dist/utils/comment-store.js.map +1 -0
  187. package/dist/utils/comment-threads.d.ts +51 -0
  188. package/dist/utils/comment-threads.d.ts.map +1 -0
  189. package/dist/utils/comment-threads.js +76 -0
  190. package/dist/utils/comment-threads.js.map +1 -0
  191. package/dist/utils/concat.d.ts +19 -0
  192. package/dist/utils/concat.d.ts.map +1 -0
  193. package/dist/utils/concat.js +135 -0
  194. package/dist/utils/concat.js.map +1 -0
  195. package/dist/utils/contact-sheet.d.ts +28 -0
  196. package/dist/utils/contact-sheet.d.ts.map +1 -0
  197. package/dist/utils/contact-sheet.js +65 -0
  198. package/dist/utils/contact-sheet.js.map +1 -0
  199. package/dist/utils/coverage-text.d.ts +3 -0
  200. package/dist/utils/coverage-text.d.ts.map +1 -0
  201. package/dist/utils/coverage-text.js +62 -0
  202. package/dist/utils/coverage-text.js.map +1 -0
  203. package/dist/utils/coverage.d.ts +57 -0
  204. package/dist/utils/coverage.d.ts.map +1 -0
  205. package/dist/utils/coverage.js +142 -0
  206. package/dist/utils/coverage.js.map +1 -0
  207. package/dist/utils/detail-batch.d.ts +25 -0
  208. package/dist/utils/detail-batch.d.ts.map +1 -0
  209. package/dist/utils/detail-batch.js +58 -0
  210. package/dist/utils/detail-batch.js.map +1 -0
  211. package/dist/utils/errors.d.ts +1 -1
  212. package/dist/utils/errors.d.ts.map +1 -1
  213. package/dist/utils/errors.js +19 -1
  214. package/dist/utils/errors.js.map +1 -1
  215. package/dist/utils/export-data.d.ts +41 -0
  216. package/dist/utils/export-data.d.ts.map +1 -0
  217. package/dist/utils/export-data.js +114 -0
  218. package/dist/utils/export-data.js.map +1 -0
  219. package/dist/utils/export-format.d.ts +23 -0
  220. package/dist/utils/export-format.d.ts.map +1 -0
  221. package/dist/utils/export-format.js +59 -0
  222. package/dist/utils/export-format.js.map +1 -0
  223. package/dist/utils/export-load.d.ts +28 -0
  224. package/dist/utils/export-load.d.ts.map +1 -0
  225. package/dist/utils/export-load.js +70 -0
  226. package/dist/utils/export-load.js.map +1 -0
  227. package/dist/utils/export-rows.d.ts +35 -0
  228. package/dist/utils/export-rows.d.ts.map +1 -0
  229. package/dist/utils/export-rows.js +69 -0
  230. package/dist/utils/export-rows.js.map +1 -0
  231. package/dist/utils/ffmpeg.d.ts +26 -0
  232. package/dist/utils/ffmpeg.d.ts.map +1 -0
  233. package/dist/utils/ffmpeg.js +28 -0
  234. package/dist/utils/ffmpeg.js.map +1 -0
  235. package/dist/utils/format.d.ts +23 -1
  236. package/dist/utils/format.d.ts.map +1 -1
  237. package/dist/utils/format.js +5 -1
  238. package/dist/utils/format.js.map +1 -1
  239. package/dist/utils/frame-plan.d.ts +24 -0
  240. package/dist/utils/frame-plan.d.ts.map +1 -0
  241. package/dist/utils/frame-plan.js +58 -0
  242. package/dist/utils/frame-plan.js.map +1 -0
  243. package/dist/utils/frames.d.ts +32 -0
  244. package/dist/utils/frames.d.ts.map +1 -0
  245. package/dist/utils/frames.js +60 -0
  246. package/dist/utils/frames.js.map +1 -0
  247. package/dist/utils/gif.d.ts +31 -0
  248. package/dist/utils/gif.d.ts.map +1 -0
  249. package/dist/utils/gif.js +77 -0
  250. package/dist/utils/gif.js.map +1 -0
  251. package/dist/utils/harvest-catalog.d.ts +54 -0
  252. package/dist/utils/harvest-catalog.d.ts.map +1 -0
  253. package/dist/utils/harvest-catalog.js +173 -0
  254. package/dist/utils/harvest-catalog.js.map +1 -0
  255. package/dist/utils/harvest-details.d.ts +30 -0
  256. package/dist/utils/harvest-details.d.ts.map +1 -0
  257. package/dist/utils/harvest-details.js +98 -0
  258. package/dist/utils/harvest-details.js.map +1 -0
  259. package/dist/utils/harvest-lock.d.ts +3 -0
  260. package/dist/utils/harvest-lock.d.ts.map +1 -0
  261. package/dist/utils/harvest-lock.js +26 -0
  262. package/dist/utils/harvest-lock.js.map +1 -0
  263. package/dist/utils/harvest-receipts.d.ts +14 -0
  264. package/dist/utils/harvest-receipts.d.ts.map +1 -0
  265. package/dist/utils/harvest-receipts.js +110 -0
  266. package/dist/utils/harvest-receipts.js.map +1 -0
  267. package/dist/utils/listing-cursor.d.ts +31 -0
  268. package/dist/utils/listing-cursor.d.ts.map +1 -0
  269. package/dist/utils/listing-cursor.js +39 -0
  270. package/dist/utils/listing-cursor.js.map +1 -0
  271. package/dist/utils/local-transcription.d.ts +14 -0
  272. package/dist/utils/local-transcription.d.ts.map +1 -0
  273. package/dist/utils/local-transcription.js +85 -0
  274. package/dist/utils/local-transcription.js.map +1 -0
  275. package/dist/utils/moment.d.ts +24 -0
  276. package/dist/utils/moment.d.ts.map +1 -0
  277. package/dist/utils/moment.js +22 -0
  278. package/dist/utils/moment.js.map +1 -0
  279. package/dist/utils/most-replayed.d.ts +15 -0
  280. package/dist/utils/most-replayed.d.ts.map +1 -0
  281. package/dist/utils/most-replayed.js +25 -0
  282. package/dist/utils/most-replayed.js.map +1 -0
  283. package/dist/utils/pot-preflight.d.ts +53 -0
  284. package/dist/utils/pot-preflight.d.ts.map +1 -0
  285. package/dist/utils/pot-preflight.js +146 -0
  286. package/dist/utils/pot-preflight.js.map +1 -0
  287. package/dist/utils/scenes.d.ts +39 -0
  288. package/dist/utils/scenes.d.ts.map +1 -0
  289. package/dist/utils/scenes.js +83 -0
  290. package/dist/utils/scenes.js.map +1 -0
  291. package/dist/utils/seconds.d.ts +5 -0
  292. package/dist/utils/seconds.d.ts.map +1 -0
  293. package/dist/utils/seconds.js +7 -0
  294. package/dist/utils/seconds.js.map +1 -0
  295. package/dist/utils/sleep.d.ts +9 -0
  296. package/dist/utils/sleep.d.ts.map +1 -0
  297. package/dist/utils/sleep.js +25 -0
  298. package/dist/utils/sleep.js.map +1 -0
  299. package/dist/utils/sponsorblock.d.ts +24 -0
  300. package/dist/utils/sponsorblock.d.ts.map +1 -0
  301. package/dist/utils/sponsorblock.js +153 -0
  302. package/dist/utils/sponsorblock.js.map +1 -0
  303. package/dist/utils/store-health.d.ts +37 -0
  304. package/dist/utils/store-health.d.ts.map +1 -0
  305. package/dist/utils/store-health.js +92 -0
  306. package/dist/utils/store-health.js.map +1 -0
  307. package/dist/utils/store-migrations.d.ts +33 -0
  308. package/dist/utils/store-migrations.d.ts.map +1 -0
  309. package/dist/utils/store-migrations.js +41 -0
  310. package/dist/utils/store-migrations.js.map +1 -0
  311. package/dist/utils/store-paths.d.ts +33 -0
  312. package/dist/utils/store-paths.d.ts.map +1 -0
  313. package/dist/utils/store-paths.js +48 -0
  314. package/dist/utils/store-paths.js.map +1 -0
  315. package/dist/utils/store-rows.d.ts +22 -0
  316. package/dist/utils/store-rows.d.ts.map +1 -0
  317. package/dist/utils/store-rows.js +62 -0
  318. package/dist/utils/store-rows.js.map +1 -0
  319. package/dist/utils/store-schema.d.ts +16 -0
  320. package/dist/utils/store-schema.d.ts.map +1 -0
  321. package/dist/utils/store-schema.js +168 -0
  322. package/dist/utils/store-schema.js.map +1 -0
  323. package/dist/utils/store.d.ts +34 -0
  324. package/dist/utils/store.d.ts.map +1 -0
  325. package/dist/utils/store.js +157 -0
  326. package/dist/utils/store.js.map +1 -0
  327. package/dist/utils/transcript-cache.d.ts +5 -1
  328. package/dist/utils/transcript-cache.d.ts.map +1 -1
  329. package/dist/utils/transcript-cache.js +31 -50
  330. package/dist/utils/transcript-cache.js.map +1 -1
  331. package/dist/utils/transcript-files.d.ts +24 -0
  332. package/dist/utils/transcript-files.d.ts.map +1 -0
  333. package/dist/utils/transcript-files.js +61 -0
  334. package/dist/utils/transcript-files.js.map +1 -0
  335. package/dist/utils/transcript.d.ts +3 -0
  336. package/dist/utils/transcript.d.ts.map +1 -1
  337. package/dist/utils/transcript.js +2 -0
  338. package/dist/utils/transcript.js.map +1 -1
  339. package/dist/utils/upload-check.d.ts +38 -0
  340. package/dist/utils/upload-check.d.ts.map +1 -0
  341. package/dist/utils/upload-check.js +93 -0
  342. package/dist/utils/upload-check.js.map +1 -0
  343. package/dist/utils/validate.d.ts +2 -0
  344. package/dist/utils/validate.d.ts.map +1 -1
  345. package/dist/utils/validate.js +4 -0
  346. package/dist/utils/validate.js.map +1 -1
  347. package/dist/utils/video-detail-store.d.ts +47 -0
  348. package/dist/utils/video-detail-store.d.ts.map +1 -0
  349. package/dist/utils/video-detail-store.js +89 -0
  350. package/dist/utils/video-detail-store.js.map +1 -0
  351. package/dist/utils/video-stats-cache.d.ts +16 -0
  352. package/dist/utils/video-stats-cache.d.ts.map +1 -0
  353. package/dist/utils/video-stats-cache.js +81 -0
  354. package/dist/utils/video-stats-cache.js.map +1 -0
  355. package/dist/utils/video-stats-schema.d.ts +187 -0
  356. package/dist/utils/video-stats-schema.d.ts.map +1 -0
  357. package/dist/utils/video-stats-schema.js +50 -0
  358. package/dist/utils/video-stats-schema.js.map +1 -0
  359. package/dist/utils/video-stats-storage.d.ts +16 -0
  360. package/dist/utils/video-stats-storage.d.ts.map +1 -0
  361. package/dist/utils/video-stats-storage.js +37 -0
  362. package/dist/utils/video-stats-storage.js.map +1 -0
  363. package/dist/utils/video-stats.d.ts +82 -0
  364. package/dist/utils/video-stats.d.ts.map +1 -0
  365. package/dist/utils/video-stats.js +108 -0
  366. package/dist/utils/video-stats.js.map +1 -0
  367. package/dist/utils/video-store.d.ts +69 -0
  368. package/dist/utils/video-store.d.ts.map +1 -0
  369. package/dist/utils/video-store.js +77 -0
  370. package/dist/utils/video-store.js.map +1 -0
  371. package/dist/utils/video-stream.d.ts +21 -0
  372. package/dist/utils/video-stream.d.ts.map +1 -0
  373. package/dist/utils/video-stream.js +36 -0
  374. package/dist/utils/video-stream.js.map +1 -0
  375. package/dist/utils/whisper.d.ts +39 -0
  376. package/dist/utils/whisper.d.ts.map +1 -0
  377. package/dist/utils/whisper.js +137 -0
  378. package/dist/utils/whisper.js.map +1 -0
  379. package/dist/utils/youtube-channel.d.ts +13 -2
  380. package/dist/utils/youtube-channel.d.ts.map +1 -1
  381. package/dist/utils/youtube-channel.js +39 -3
  382. package/dist/utils/youtube-channel.js.map +1 -1
  383. package/dist/utils/youtube-schemas.d.ts +104 -0
  384. package/dist/utils/youtube-schemas.d.ts.map +1 -1
  385. package/dist/utils/youtube-schemas.js +32 -0
  386. package/dist/utils/youtube-schemas.js.map +1 -1
  387. package/dist/utils/youtube-video.d.ts +22 -1
  388. package/dist/utils/youtube-video.d.ts.map +1 -1
  389. package/dist/utils/youtube-video.js +40 -28
  390. package/dist/utils/youtube-video.js.map +1 -1
  391. package/dist/utils/ytdlp-limiter.d.ts +3 -0
  392. package/dist/utils/ytdlp-limiter.d.ts.map +1 -1
  393. package/dist/utils/ytdlp-limiter.js +19 -3
  394. package/dist/utils/ytdlp-limiter.js.map +1 -1
  395. package/dist/utils/ytdlp-pacer.d.ts +64 -0
  396. package/dist/utils/ytdlp-pacer.d.ts.map +1 -0
  397. package/dist/utils/ytdlp-pacer.js +165 -0
  398. package/dist/utils/ytdlp-pacer.js.map +1 -0
  399. package/dist/utils/ytdlp-stream.d.ts +32 -0
  400. package/dist/utils/ytdlp-stream.d.ts.map +1 -0
  401. package/dist/utils/ytdlp-stream.js +61 -0
  402. package/dist/utils/ytdlp-stream.js.map +1 -0
  403. package/dist/utils/ytdlp.d.ts +10 -0
  404. package/dist/utils/ytdlp.d.ts.map +1 -1
  405. package/dist/utils/ytdlp.js +36 -25
  406. package/dist/utils/ytdlp.js.map +1 -1
  407. package/package.json +10 -4
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/youtube-knowledge-mcp.svg)](https://www.npmjs.com/package/youtube-knowledge-mcp)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Node.js](https://img.shields.io/badge/Node.js-22%2B-green.svg)](https://nodejs.org/)
5
+ [![Node.js](https://img.shields.io/badge/Node.js-22.13%2B-green.svg)](https://nodejs.org/)
6
6
  [![GitHub stars](https://img.shields.io/github/stars/teobouancheau/youtube-knowledge-mcp?style=social)](https://github.com/teobouancheau/youtube-knowledge-mcp)
7
7
 
8
8
  A Model Context Protocol (MCP) server that gives AI assistants the ability to search, analyze, and extract knowledge from YouTube videos. Works with Claude Desktop, Claude Code, Claude.ai, Cursor and any MCP-compatible client.
@@ -40,6 +40,19 @@ Supports both **local** (stdio) and **remote** (Streamable HTTP) transports.
40
40
  - **Read them back**, and **search across all of them** with full-text ranking
41
41
  - **Tag, retag and delete**
42
42
 
43
+ **Extract exhaustively, and prove it** (local mode)
44
+
45
+ - **Catalogue a whole channel** across every tab — videos, shorts, streams,
46
+ releases, podcasts — into a local SQLite store, resumably
47
+ - **Harvest comments with their replies**, every field YouTube returns, and
48
+ search them locally with full-text ranking and real pagination
49
+ - **A completeness receipt on every extraction**: `complete` is true only when
50
+ the server can _prove_ it holds everything in scope, so a partial harvest can
51
+ never be mistaken for a full history
52
+ - **Ask what you actually have** with `get_coverage`, which never touches the
53
+ network — cheap enough to call before every claim
54
+ - **Remove what you hold**, including one author's comments everywhere
55
+
43
56
  **Build a brain for a channel** (local mode)
44
57
 
45
58
  - **Read a whole channel** into a searchable corpus of timestamped passages, in
@@ -60,7 +73,8 @@ Supports both **local** (stdio) and **remote** (Streamable HTTP) transports.
60
73
  - WebVTT parsed by the W3C reference implementation, not a hand-written matcher
61
74
  - Typed, actionable errors — "no captions in en, try: fr, es, de" rather than a
62
75
  wall of yt-dlp stderr
63
- - Timeouts, retry with backoff, and a concurrency limit on every yt-dlp call
76
+ - Timeouts, adaptive backoff and a concurrency limit on every yt-dlp call, with
77
+ cooldowns and a circuit breaker so a long harvest survives being throttled
64
78
  - `check_health` diagnoses missing or outdated yt-dlp and ffmpeg
65
79
  - Bearer auth, a loopback default bind, an allowlist on every URL and image host, and typed error codes on every failure
66
80
  - Structured output on every tool, plus MCP resources, prompts and completions
@@ -68,7 +82,7 @@ Supports both **local** (stdio) and **remote** (Streamable HTTP) transports.
68
82
 
69
83
  ## Prerequisites
70
84
 
71
- - Node.js 22+
85
+ - Node.js 22.13+ — the version where `node:sqlite`, which the harvest store uses, is available without a flag
72
86
  - [yt-dlp](https://github.com/yt-dlp/yt-dlp#installation) — required by every tool.
73
87
  `brew install yt-dlp` (macOS) or `pip install -U yt-dlp`
74
88
  - [ffmpeg](https://ffmpeg.org/) — required for downloads, clip extraction and frame
@@ -221,9 +235,9 @@ a cold start. Any paid plan removes that.
221
235
 
222
236
  ## MCP Tools
223
237
 
224
- 37 tools. The 15 read-only ones work over both transports; the 22 that touch
225
- your filesystem are registered only in local (stdio) mode, so a remote
226
- deployment cannot reach the host's disk.
238
+ 58 tools. The 19 read-only ones work over both transports; the 39 that touch
239
+ your filesystem or run ffmpeg are registered only in local (stdio) mode, so a
240
+ remote deployment cannot reach the host's disk or spawn processes on it.
227
241
 
228
242
  Every tool returns human-readable text **and** typed structured output, and
229
243
  reports failures as an actionable message — `[NO_CAPTIONS] No "en" captions are
@@ -231,19 +245,23 @@ available for this video. Call get_transcript again with one of: fr, es, de.`
231
245
 
232
246
  ### Discovery — remote + local
233
247
 
234
- | Tool | Key parameters | Returns |
235
- | ------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------- |
236
- | `search_videos` | `query`, `limit` | Matching videos with durations, channels and view counts |
237
- | `search_channels` | `query`, `limit` | Matching channels with subscriber counts |
238
- | `fetch_videos` | `url`, `limit` | Videos in a playlist or channel, with thumbnail URLs |
239
- | `get_video_info` | `video` | Title, channel, duration, views, likes, description, tags |
240
- | `get_channel_info` | `channel` | Name, handle, subscriber count, description, avatar and banner |
241
- | `get_playlist_info` | `url` | Title, channel, video count, last updated |
242
- | `get_chapters` | `video` | Chapter titles with start/end times and deep links |
243
- | `get_comments` | `video`, `limit` | Top-level comments by popularity |
244
- | `list_formats` | `video` | Available formats grouped by video+audio, video-only, audio-only |
245
- | `get_thumbnail` | `video`, `channel`, `image`, `quality` | A video thumbnail, channel avatar or banner as an image, with its real size |
246
- | `check_health` | — | yt-dlp and ffmpeg status, versions, staleness warnings, and which session options are set |
248
+ | Tool | Key parameters | Returns |
249
+ | ------------------------ | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
250
+ | `search_videos` | `query`, `limit` | Matching videos with durations, channels and view counts |
251
+ | `search_channels` | `query`, `limit` | Matching channels with subscriber counts |
252
+ | `fetch_videos` | `url`, `limit`, `cursor` | One page of a playlist or channel, with a cursor. `total` is present only when YouTube states one |
253
+ | `get_video_info` | `video` | Title, channel, duration, views, likes, description, tags |
254
+ | `get_channel_info` | `channel` | Name, handle, subscriber count, description, avatar, banner, verified badge and keywords |
255
+ | `get_playlist_info` | `url` | Title, channel, video count, last updated |
256
+ | `get_video_details` | `video`, `heatmap`, `refresh` | Most-replayed moments with links, category, licence, language, age limit, music credits, frame size, caption inventory |
257
+ | `list_captions` | `video` | Caption languages split into human-made and automatic, and the spoken language |
258
+ | `list_channel_playlists` | `channel`, `limit` | A channel's public playlists with titles and links |
259
+ | `get_sponsor_segments` | `video`, `categories` | Community-marked sponsor, intro, outro and filler segments with links (SponsorBlock) |
260
+ | `get_chapters` | `video` | Chapter titles with start/end times and deep links |
261
+ | `get_comments` | `video`, `limit`, `includeReplies`, `sort` | Comments with replies and a completeness receipt saying how many of the video's comments this is |
262
+ | `list_formats` | `video` | Available formats grouped by video+audio, video-only, audio-only |
263
+ | `get_thumbnail` | `video`, `channel`, `image`, `quality` | A video thumbnail, channel avatar or banner as an image, with its real size |
264
+ | `check_health` | — | yt-dlp and ffmpeg status, versions, staleness warnings, and which session options are set |
247
265
 
248
266
  ### Transcripts — remote + local
249
267
 
@@ -260,20 +278,57 @@ pieces instead of returning 100,000+ tokens at once.
260
278
 
261
279
  ### Extraction for editing — local only
262
280
 
263
- | Tool | Key parameters | Returns |
264
- | -------------------- | -------------------------------------------------------------------------- | ---------------------------- |
265
- | `extract_clip` | `video`, `start`+`end` or `chapter`, `quality`, `preciseCuts`, `outputDir` | Path to the cut video |
266
- | `extract_audio_clip` | `video`, `start`+`end` or `chapter`, `audioFormat`, `outputDir` | Path to the audio file |
267
- | `extract_clips` | `video`, `ranges` (up to 20), `quality`, `preciseCuts`, `outputDir` | One file per range |
268
- | `extract_frame` | `video`, `timestamp`, `format`, `outputDir` | Path to a PNG or JPG still |
269
- | `export_subtitles` | `video`, `format` (srt/vtt/txt), `language`, `outputDir` | Path to the subtitle file |
270
- | `download_video` | `video`, `quality`, `formatId`, `outputDir` | Path to the downloaded video |
281
+ | Tool | Key parameters | Returns |
282
+ | -------------------- | -------------------------------------------------------------------------- | ------------------------------------------ |
283
+ | `extract_clip` | `video`, `start`+`end` or `chapter`, `quality`, `preciseCuts`, `outputDir` | Path to the cut video |
284
+ | `extract_audio_clip` | `video`, `start`+`end` or `chapter`, `audioFormat`, `outputDir` | Path to the audio file |
285
+ | `extract_clips` | `video`, `ranges` (up to 20), `quality`, `preciseCuts`, `outputDir` | One file per range |
286
+ | `extract_frame` | `video`, `timestamp`, `format`, `outputDir` | A PNG or JPG still, saved and shown inline |
287
+ | `extract_gif` | `video`, `start`+`end` or `chapter`, `width`, `fps`, `outputDir` | Path to a looping GIF, up to 15 s |
288
+ | `concat_clips` | `clips` (2 to 20 paths), `name`, `outputDir` | Path to one video joining them, re-encoded |
289
+ | `export_subtitles` | `video`, `format` (srt/vtt/txt), `language`, `outputDir` | Path to the subtitle file |
290
+ | `download_video` | `video`, `quality`, `formatId`, `outputDir` | Path to the downloaded video |
271
291
 
272
292
  Clips are cut with `--download-sections`, so only the byte range covering the
273
293
  window is fetched rather than the whole file. `preciseCuts` (default `true`)
274
294
  cuts exactly at the requested times; set it to `false` for a faster
275
295
  keyframe-aligned cut. All of these require ffmpeg.
276
296
 
297
+ ### Looking at a video — local only
298
+
299
+ Everything above works from words. These work from pixels: each tool returns
300
+ images the model can read, and writes nothing to disk. All of them require ffmpeg.
301
+
302
+ | Tool | Key parameters | Returns |
303
+ | ----------------------- | --------------------------------------------------------- | --------------------------------------------------------------- |
304
+ | `extract_frames` | `video`, `timestamps` or `count`, `start`, `end`, `width` | Up to 12 frames as images, each labelled with its moment |
305
+ | `extract_contact_sheet` | `video`, `count` (up to 24), `start`, `end`, `columns` | One image tiling the frames, with the timestamp of every cell |
306
+ | `detect_scenes` | `video`, `start`, `end`, `threshold` | Timestamps where the video cuts, with links (up to 15 min/call) |
307
+
308
+ Start with `extract_contact_sheet` to see what a video looks like, then
309
+ `extract_frames` at the moments that matter, found with `search_transcript` or
310
+ `detect_scenes`. Frames are shrunk to `width` and never enlarged.
311
+
312
+ ### Videos with no captions — local only
313
+
314
+ | Tool | Key parameters | Returns |
315
+ | ------------------ | ------------------------------ | ---------------------------------------------------------- |
316
+ | `transcribe_video` | `video`, `language`, `refresh` | A transcription made on this machine, kept for later reads |
317
+
318
+ When `get_transcript` reports `NO_CAPTIONS`, `transcribe_video` downloads the
319
+ audio and runs [whisper.cpp](https://github.com/ggml-org/whisper.cpp) over it.
320
+ It is optional and nothing runs unless you call it. Install whisper.cpp so that
321
+ `whisper-cli` is on your `PATH` (macOS: `brew install whisper.cpp`), download a
322
+ ggml model such as `ggml-base.bin`, and set `YOUTUBE_MCP_WHISPER_MODEL` to its
323
+ path. `check_health` reports whether both are in place.
324
+
325
+ Always pass `language`: auto-detection on a small model took English speech for
326
+ French. The result is kept beside the video's captions, never over them, and
327
+ `get_transcript`, `search_transcript`, `export_subtitles` and the channel brains
328
+ read it with `source: "local-asr"` so a machine's guess is never mistaken for
329
+ YouTube's captions. Accuracy depends on the model you choose; names and rare
330
+ words are the first to suffer.
331
+
277
332
  ### Knowledge library — local only
278
333
 
279
334
  | Tool | Key parameters | Returns |
@@ -286,16 +341,49 @@ keyframe-aligned cut. All of these require ffmpeg.
286
341
  | `delete_library_item` | `videoId`, `contentType` | What was deleted |
287
342
  | `rebuild_library_index` | — | Number of notes reindexed |
288
343
 
344
+ ### Exhaustive harvest — local only
345
+
346
+ Extraction that stores what it reads, and proves what it holds. Every tool here
347
+ returns a **completeness receipt**: `complete` is true only when the server can
348
+ prove it has everything in scope, and a consumer must not describe the data as a
349
+ full history while it is false.
350
+
351
+ | Tool | Key parameters | Returns |
352
+ | ------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------- |
353
+ | `harvest_channel` | `channel`, `maxVideos` | Every video across all tabs, catalogued, with a receipt |
354
+ | `harvest_details` | `channel`, `maxVideos`, `retryUnreadable` | The full record of each catalogued video, kept in the store, with a receipt |
355
+ | `check_new_uploads` | `channel`, `lookback` | Videos the channel lists that the catalogue lacks; writes nothing |
356
+ | `harvest_comments` | `video`, `maxComments`, `sort`, `maxRepliesPerThread` | Comments and replies stored locally, with a receipt |
357
+ | `get_coverage` | `scope`, `incompleteOnly`, `verify`, `limit`, `offset` | What the server can prove it holds, and what it cannot |
358
+ | `query_comments` | `video`, `channel`, `match`, `author`, `threadOf`, `order`, `limit` | Full-text search over stored comments, with real pagination |
359
+ | `query_videos` | `channel`, `match`, `since`, `until`, `withComments`, `order`, `limit` | The catalogued videos, filtered and sorted |
360
+ | `prune_harvest` | `channel`, `video`, `author`, `scope`, `confirm`, `vacuum` | What was removed from the store |
361
+ | `export_data` | `dataset`, `format`, `channel`, `video`, `limit`, `outputDir` | JSON, CSV or Markdown file of harvested rows, with their receipts |
362
+ | `repair_store` | `confirm` | Moves a damaged store aside and starts a fresh one |
363
+
364
+ `get_coverage` never contacts YouTube, so it is cheap enough to call before
365
+ making any claim about the data. Check `anyIncomplete` first.
366
+
367
+ There is no cursor for comments: YouTube exposes none for a live read, so
368
+ `harvest_comments` cannot page. To get more, run it again with a larger
369
+ `maxComments` — rows are upserted on the comment id, so a re-run costs requests
370
+ and never data.
371
+
372
+ `prune_harvest` exists because the store holds personal data at scale: display
373
+ names, channel ids and free-text opinions from people who never used this tool.
374
+ The `author` filter is the per-person erasure path.
375
+
289
376
  ### Channel brains — local only
290
377
 
291
- | Tool | Key parameters | Returns |
292
- | -------------------- | ----------------------------------------------------------------- | ------------------------------------------------ |
293
- | `build_brain` | `channel`, `maxVideos`, `language`, `since`, `minDurationSeconds` | What was read, what was ruled out, and the stats |
294
- | `ask_brain` | `channel`, `query`, `limit`, `offset` | Passages with timestamps and `?t=` links |
295
- | `list_brains` | — | Every brain built locally |
296
- | `get_brain_info` | `channel`, `includeVideos` | Coverage, statistics and repeated phrases |
297
- | `save_brain_profile` | `channel`, `content` | Path to the saved profile |
298
- | `delete_brain` | `channel` | What was removed |
378
+ | Tool | Key parameters | Returns |
379
+ | -------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------- |
380
+ | `build_brain` | `channel`, `maxVideos`, `language`, `since`, `minDurationSeconds` | What was read, what was ruled out, and the stats |
381
+ | `ask_brain` | `channel`, `query`, `limit`, `offset` | Passages with timestamps and `?t=` links |
382
+ | `ask_brains` | `query`, `channels`, `limit` | The best passages across several brains, each naming its channel |
383
+ | `list_brains` | — | Every brain built locally |
384
+ | `get_brain_info` | `channel`, `includeVideos` | Coverage, statistics and repeated phrases |
385
+ | `save_brain_profile` | `channel`, `content` | Path to the saved profile |
386
+ | `delete_brain` | `channel` | What was removed |
299
387
 
300
388
  `build_brain` is the only one that touches the network. The rest resolve a
301
389
  channel from what is already on disk, so they work offline and cost nothing to
@@ -392,6 +480,8 @@ All optional.
392
480
  | `MCP_MAX_SESSIONS` | `1000` | Reject new sessions past this many |
393
481
  | `YOUTUBE_MCP_MAX_CONCURRENCY` | `3` | Concurrent yt-dlp processes |
394
482
  | `YOUTUBE_MCP_TRANSCRIPT_TTL_MS` | 30 days | Transcript cache lifetime |
483
+ | `YOUTUBE_MCP_STATS_TTL_MS` | 1 day | Per-video stats cache lifetime |
484
+ | `YOUTUBE_MCP_WHISPER_MODEL` | none | Path to a whisper.cpp ggml model file. Enables `transcribe_video`; never downloaded for you |
395
485
  | `YOUTUBE_MCP_COOKIES_FROM_BROWSER` | unset | Browser whose cookies yt-dlp should read: `brave`, `chrome`, `chromium`, `edge`, `firefox`, `opera`, `safari`, `vivaldi` or `whale`. See Signed-in content |
396
486
  | `YOUTUBE_MCP_COOKIES_FILE` | unset | A Netscape-format cookies file inside your home directory, as an alternative to a browser |
397
487
  | `YOUTUBE_MCP_PROXY` | unset | An `http`, `https`, `socks4` or `socks5` proxy URL for yt-dlp |
@@ -549,7 +639,7 @@ npm run start:http # Run server (HTTP)
549
639
  npm run validate # Typecheck + lint + format check + test
550
640
  ```
551
641
 
552
- CI runs the same gate on Node 22 and 24 for every push and pull request,
642
+ CI runs the same gate on Node 22.22, 22 and 24 for every push and pull request,
553
643
  then boots the built server as a real MCP client to verify the manifest.
554
644
 
555
645
  ## Contributing
@@ -228,6 +228,8 @@ export declare const brainManifestSchema: z.ZodObject<{
228
228
  description: z.ZodString;
229
229
  avatarUrl: z.ZodOptional<z.ZodString>;
230
230
  bannerUrl: z.ZodOptional<z.ZodString>;
231
+ isVerified: z.ZodOptional<z.ZodBoolean>;
232
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
231
233
  }, "strip", z.ZodTypeAny, {
232
234
  description: string;
233
235
  name: string;
@@ -235,8 +237,10 @@ export declare const brainManifestSchema: z.ZodObject<{
235
237
  handle: string;
236
238
  subscriberCount: number;
237
239
  channelUrl: string;
240
+ tags?: string[] | undefined;
238
241
  avatarUrl?: string | undefined;
239
242
  bannerUrl?: string | undefined;
243
+ isVerified?: boolean | undefined;
240
244
  }, {
241
245
  description: string;
242
246
  name: string;
@@ -244,8 +248,10 @@ export declare const brainManifestSchema: z.ZodObject<{
244
248
  handle: string;
245
249
  subscriberCount: number;
246
250
  channelUrl: string;
251
+ tags?: string[] | undefined;
247
252
  avatarUrl?: string | undefined;
248
253
  bannerUrl?: string | undefined;
254
+ isVerified?: boolean | undefined;
249
255
  }>;
250
256
  /**
251
257
  * A brain is built from one caption language. Defaulted rather than required
@@ -351,8 +357,10 @@ export declare const brainManifestSchema: z.ZodObject<{
351
357
  handle: string;
352
358
  subscriberCount: number;
353
359
  channelUrl: string;
360
+ tags?: string[] | undefined;
354
361
  avatarUrl?: string | undefined;
355
362
  bannerUrl?: string | undefined;
363
+ isVerified?: boolean | undefined;
356
364
  };
357
365
  version: number;
358
366
  videos: Record<string, {
@@ -399,8 +407,10 @@ export declare const brainManifestSchema: z.ZodObject<{
399
407
  handle: string;
400
408
  subscriberCount: number;
401
409
  channelUrl: string;
410
+ tags?: string[] | undefined;
402
411
  avatarUrl?: string | undefined;
403
412
  bannerUrl?: string | undefined;
413
+ isVerified?: boolean | undefined;
404
414
  };
405
415
  version: number;
406
416
  videos: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"brain-schemas.d.ts","sourceRoot":"","sources":["../src/brain-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;GAMG;AAEH,qDAAqD;AACrD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAchC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,uDAAuD;AACvD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAO3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;EAI5B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;EAGpC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,4BAA4B;AAC5B,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAG9B;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMH,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,8BAA8B;AAC9B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY7B,CAAC"}
1
+ {"version":3,"file":"brain-schemas.d.ts","sourceRoot":"","sources":["../src/brain-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;GAMG;AAEH,qDAAqD;AACrD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAchC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,uDAAuD;AACvD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAO3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;EAI5B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;EAGpC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,4BAA4B;AAC5B,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAG9B;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMH,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,8BAA8B;AAC9B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY7B,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The shapes a completeness receipt is made of.
4
+ *
5
+ * This server exists to extract everything YouTube will serve, and the failure
6
+ * mode that matters is not "we got 3%" — it is "we got 3% and reported 100%".
7
+ * A receipt travels with every extraction result so a consumer can never
8
+ * describe a sample as a full history by accident.
9
+ *
10
+ * The invariants that make `complete` mean something live in
11
+ * `utils/coverage.ts`, which is the only place allowed to build one.
12
+ */
13
+ export declare const harvestScopeSchema: z.ZodEnum<["channel-catalog", "video-details", "video-comments"]>;
14
+ export type HarvestScope = z.infer<typeof harvestScopeSchema>;
15
+ export declare const completenessReasonSchema: z.ZodEnum<["COMPLETE", "CAP_REACHED", "BUDGET_SPENT", "RATE_LIMITED", "CANCELLED", "TIMEOUT", "SOURCE_REFUSED", "COMMENTS_DISABLED", "SOURCE_SILENT", "PARTIAL_ERROR", "NOT_ATTEMPTED"]>;
16
+ export type CompletenessReason = z.infer<typeof completenessReasonSchema>;
17
+ /**
18
+ * Where a total came from.
19
+ *
20
+ * `source-exhausted` is the one value that is not a number YouTube reported:
21
+ * it means the listing ended on its own, which is its own kind of proof.
22
+ */
23
+ export declare const expectedSourceSchema: z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted", "store:catalog"]>;
24
+ export type ExpectedSource = z.infer<typeof expectedSourceSchema>;
25
+ export declare const coverageSchema: z.ZodObject<{
26
+ scope: z.ZodEnum<["channel-catalog", "video-details", "video-comments"]>;
27
+ targetId: z.ZodString;
28
+ complete: z.ZodBoolean;
29
+ reason: z.ZodEnum<["COMPLETE", "CAP_REACHED", "BUDGET_SPENT", "RATE_LIMITED", "CANCELLED", "TIMEOUT", "SOURCE_REFUSED", "COMMENTS_DISABLED", "SOURCE_SILENT", "PARTIAL_ERROR", "NOT_ATTEMPTED"]>;
30
+ have: z.ZodNumber;
31
+ expected: z.ZodOptional<z.ZodNumber>;
32
+ expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted", "store:catalog"]>>;
33
+ ranToExhaustion: z.ZodOptional<z.ZodBoolean>;
34
+ source: z.ZodString;
35
+ harvestedAt: z.ZodString;
36
+ staleAfter: z.ZodOptional<z.ZodString>;
37
+ limitApplied: z.ZodOptional<z.ZodNumber>;
38
+ sortApplied: z.ZodOptional<z.ZodEnum<["top", "new"]>>;
39
+ resumeToken: z.ZodOptional<z.ZodString>;
40
+ note: z.ZodOptional<z.ZodString>;
41
+ }, "strip", z.ZodTypeAny, {
42
+ source: string;
43
+ have: number;
44
+ scope: "channel-catalog" | "video-details" | "video-comments";
45
+ targetId: string;
46
+ complete: boolean;
47
+ reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
48
+ harvestedAt: string;
49
+ expected?: number | undefined;
50
+ note?: string | undefined;
51
+ ranToExhaustion?: boolean | undefined;
52
+ expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
53
+ staleAfter?: string | undefined;
54
+ limitApplied?: number | undefined;
55
+ sortApplied?: "top" | "new" | undefined;
56
+ resumeToken?: string | undefined;
57
+ }, {
58
+ source: string;
59
+ have: number;
60
+ scope: "channel-catalog" | "video-details" | "video-comments";
61
+ targetId: string;
62
+ complete: boolean;
63
+ reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
64
+ harvestedAt: string;
65
+ expected?: number | undefined;
66
+ note?: string | undefined;
67
+ ranToExhaustion?: boolean | undefined;
68
+ expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
69
+ staleAfter?: string | undefined;
70
+ limitApplied?: number | undefined;
71
+ sortApplied?: "top" | "new" | undefined;
72
+ resumeToken?: string | undefined;
73
+ }>;
74
+ export type Coverage = z.infer<typeof coverageSchema>;
75
+ //# sourceMappingURL=harvest-schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harvest-schemas.d.ts","sourceRoot":"","sources":["../src/harvest-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,kBAAkB,mEAO7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,wBAAwB,0LAqBnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,qGAS/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The shapes a completeness receipt is made of.
4
+ *
5
+ * This server exists to extract everything YouTube will serve, and the failure
6
+ * mode that matters is not "we got 3%" — it is "we got 3% and reported 100%".
7
+ * A receipt travels with every extraction result so a consumer can never
8
+ * describe a sample as a full history by accident.
9
+ *
10
+ * The invariants that make `complete` mean something live in
11
+ * `utils/coverage.ts`, which is the only place allowed to build one.
12
+ */
13
+ export const harvestScopeSchema = z.enum([
14
+ /** Which videos a channel has. */
15
+ 'channel-catalog',
16
+ /** Full per-video metadata snapshots. */
17
+ 'video-details',
18
+ /** Comments and replies for one video. */
19
+ 'video-comments',
20
+ ]);
21
+ export const completenessReasonSchema = z.enum([
22
+ /** Provably everything: the source stated a total and we hold it, or the source ran out. */
23
+ 'COMPLETE',
24
+ /** The caller's own limit stopped it. */
25
+ 'CAP_REACHED',
26
+ /** The wall-clock budget for this call ran out. */
27
+ 'BUDGET_SPENT',
28
+ /** YouTube throttled this client. */
29
+ 'RATE_LIMITED',
30
+ /** The MCP client aborted the request. */
31
+ 'CANCELLED',
32
+ 'TIMEOUT',
33
+ /** BOT_CHECK, LOGIN_REQUIRED, PRIVATE, AGE_GATED or MEMBERS_ONLY. */
34
+ 'SOURCE_REFUSED',
35
+ /** Comments are turned off for this video, so zero is the true total. */
36
+ 'COMMENTS_DISABLED',
37
+ /** The source states no total, so exhaustion is unprovable. */
38
+ 'SOURCE_SILENT',
39
+ /** Some items failed; each cost only itself. */
40
+ 'PARTIAL_ERROR',
41
+ 'NOT_ATTEMPTED',
42
+ ]);
43
+ /**
44
+ * Where a total came from.
45
+ *
46
+ * `source-exhausted` is the one value that is not a number YouTube reported:
47
+ * it means the listing ended on its own, which is its own kind of proof.
48
+ */
49
+ export const expectedSourceSchema = z.enum([
50
+ 'youtube:comment_count',
51
+ 'youtube:playlist_count',
52
+ 'source-exhausted',
53
+ /**
54
+ * The channel catalogue held in the store. Only ever the total of a catalogue whose own
55
+ * receipt is complete, so it is exactly as trustworthy as that receipt and no more.
56
+ */
57
+ 'store:catalog',
58
+ ]);
59
+ export const coverageSchema = z.object({
60
+ scope: harvestScopeSchema,
61
+ targetId: z.string().describe('Channel id for a catalog, video id for details or comments'),
62
+ complete: z
63
+ .boolean()
64
+ .describe('True ONLY when this server can prove it holds every item in scope. False means the ' +
65
+ 'data is a SAMPLE. A consumer must not describe it as a full history while this is false.'),
66
+ reason: completenessReasonSchema.describe('Why complete is what it is. Always present, including when complete is true.'),
67
+ have: z
68
+ .number()
69
+ .int()
70
+ .nonnegative()
71
+ .describe('Items this store actually holds for this target, counted from the store.'),
72
+ expected: z
73
+ .number()
74
+ .int()
75
+ .nonnegative()
76
+ .optional()
77
+ .describe('The total the SOURCE states. Absent when the source states none — never inferred, ' +
78
+ 'never copied from have. Absent with complete:false means "unknown how much is missing".'),
79
+ expectedSource: expectedSourceSchema
80
+ .optional()
81
+ .describe('Where expected came from. Absent if and only if expected is absent.'),
82
+ ranToExhaustion: z
83
+ .boolean()
84
+ .optional()
85
+ .describe("Whether the source's own iteration finished rather than being cut off. Necessary for " +
86
+ 'completeness but not sufficient: a cap also ends iteration.'),
87
+ source: z.string().describe('The exact extraction path, including tool version and flags.'),
88
+ harvestedAt: z.string().describe('ISO-8601 of the last item written for this target'),
89
+ staleAfter: z
90
+ .string()
91
+ .optional()
92
+ .describe('ISO-8601 after which this should be re-checked. Comments accrue, so a complete ' +
93
+ 'receipt goes stale without becoming wrong.'),
94
+ limitApplied: z
95
+ .number()
96
+ .int()
97
+ .positive()
98
+ .optional()
99
+ .describe('The cap the caller asked for. Present if and only if one was applied.'),
100
+ sortApplied: z
101
+ .enum(['top', 'new'])
102
+ .optional()
103
+ .describe('Ordering the source applied. A capped "top" harvest is a BIASED PREFIX of a stream, ' +
104
+ 'not a random sample.'),
105
+ resumeToken: z
106
+ .string()
107
+ .optional()
108
+ .describe('Opaque. Pass to the same tool to continue. Absent if and only if complete.'),
109
+ note: z.string().optional(),
110
+ });
111
+ //# sourceMappingURL=harvest-schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harvest-schemas.js","sourceRoot":"","sources":["../src/harvest-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC;IACvC,kCAAkC;IAClC,iBAAiB;IACjB,yCAAyC;IACzC,eAAe;IACf,0CAA0C;IAC1C,gBAAgB;CACjB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC7C,4FAA4F;IAC5F,UAAU;IACV,yCAAyC;IACzC,aAAa;IACb,mDAAmD;IACnD,cAAc;IACd,qCAAqC;IACrC,cAAc;IACd,0CAA0C;IAC1C,WAAW;IACX,SAAS;IACT,qEAAqE;IACrE,gBAAgB;IAChB,yEAAyE;IACzE,mBAAmB;IACnB,+DAA+D;IAC/D,eAAe;IACf,gDAAgD;IAChD,eAAe;IACf,eAAe;CAChB,CAAC,CAAC;AAGH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC;IACzC,uBAAuB;IACvB,wBAAwB;IACxB,kBAAkB;IAClB;;;OAGG;IACH,eAAe;CAChB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,kBAAkB;IACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;IAE3F,QAAQ,EAAE,CAAC;SACR,OAAO,EAAE;SACT,QAAQ,CACP,qFAAqF;QACnF,0FAA0F,CAC7F;IAEH,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CACvC,8EAA8E,CAC/E;IAED,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,EAAE;SACL,WAAW,EAAE;SACb,QAAQ,CAAC,0EAA0E,CAAC;IAEvF,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,EAAE;SACL,WAAW,EAAE;SACb,QAAQ,EAAE;SACV,QAAQ,CACP,oFAAoF;QAClF,yFAAyF,CAC5F;IAEH,cAAc,EAAE,oBAAoB;SACjC,QAAQ,EAAE;SACV,QAAQ,CAAC,qEAAqE,CAAC;IAElF,eAAe,EAAE,CAAC;SACf,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,uFAAuF;QACrF,6DAA6D,CAChE;IAEH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;IAE3F,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;IAErF,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,iFAAiF;QAC/E,4CAA4C,CAC/C;IAEH,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,QAAQ,CAAC,uEAAuE,CAAC;IAEpF,WAAW,EAAE,CAAC;SACX,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SACpB,QAAQ,EAAE;SACV,QAAQ,CACP,sFAAsF;QACpF,sBAAsB,CACzB;IAEH,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,4EAA4E,CAAC;IAEzF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"brain-tools.d.ts","sourceRoot":"","sources":["../../src/registry/brain-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAwB7D,yMAAyM;AACzM,eAAO,MAAM,UAAU,EAAE,cAAc,EAsGtC,CAAC"}
1
+ {"version":3,"file":"brain-tools.d.ts","sourceRoot":"","sources":["../../src/registry/brain-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAyB7D,yMAAyM;AACzM,eAAO,MAAM,UAAU,EAAE,cAAc,EAsHtC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { defineTool } from './types.js';
2
2
  import { askBrainSchema, askBrainOutputSchema, askBrainHandler } from '../tools/ask-brain.js';
3
+ import { askBrainsSchema, askBrainsOutputSchema, askBrainsHandler } from '../tools/ask-brains.js';
3
4
  import { listBrainsSchema, listBrainsOutputSchema, listBrainsHandler, getBrainInfoSchema, getBrainInfoOutputSchema, getBrainInfoHandler, } from '../tools/brain-info.js';
4
5
  import { buildBrainSchema, buildBrainOutputSchema, buildBrainHandler, } from '../tools/build-brain.js';
5
6
  import { saveBrainProfileSchema, saveBrainProfileOutputSchema, saveBrainProfileHandler, deleteBrainSchema, deleteBrainOutputSchema, deleteBrainHandler, } from '../tools/manage-brain.js';
@@ -39,6 +40,21 @@ export const brainTools = [
39
40
  },
40
41
  handler: askBrainHandler,
41
42
  }),
43
+ defineTool({
44
+ name: 'ask_brains',
45
+ mode: 'stdio',
46
+ title: 'Ask Several Channel Brains',
47
+ description: 'Put one question to several creators at once. Searches every brain built with build_brain, or the channels you name, and returns the best passages across them, each naming its channel with the timestamp and a link that opens the video there. Results are interleaved by rank because scores from different channels are not comparable.',
48
+ inputSchema: askBrainsSchema,
49
+ outputSchema: askBrainsOutputSchema,
50
+ annotations: {
51
+ readOnlyHint: true,
52
+ destructiveHint: false,
53
+ idempotentHint: true,
54
+ openWorldHint: false,
55
+ },
56
+ handler: askBrainsHandler,
57
+ }),
42
58
  defineTool({
43
59
  name: 'list_brains',
44
60
  mode: 'stdio',
@@ -1 +1 @@
1
- {"version":3,"file":"brain-tools.js","sourceRoot":"","sources":["../../src/registry/brain-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"brain-tools.js","sourceRoot":"","sources":["../../src/registry/brain-tools.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"channel-tools.d.ts","sourceRoot":"","sources":["../../src/registry/channel-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAiB7D,2CAA2C;AAC3C,eAAO,MAAM,YAAY,EAAE,cAAc,EAiDxC,CAAC"}
1
+ {"version":3,"file":"channel-tools.d.ts","sourceRoot":"","sources":["../../src/registry/channel-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAsB7D,2CAA2C;AAC3C,eAAO,MAAM,YAAY,EAAE,cAAc,EAiExC,CAAC"}
@@ -2,6 +2,7 @@ import { defineTool } from './types.js';
2
2
  import { getChannelInfoSchema, getChannelInfoOutputSchema, getChannelInfoHandler, } from '../tools/get-channel-info.js';
3
3
  import { getPlaylistInfoSchema, getPlaylistInfoOutputSchema, getPlaylistInfoHandler, } from '../tools/get-playlist-info.js';
4
4
  import { searchChannelsSchema, searchChannelsOutputSchema, searchChannelsHandler, } from '../tools/search-channels.js';
5
+ import { listChannelPlaylistsSchema, listChannelPlaylistsOutputSchema, listChannelPlaylistsHandler, } from '../tools/list-channel-playlists.js';
5
6
  /** Channels and playlists. Remote-safe. */
6
7
  export const channelTools = [
7
8
  defineTool({
@@ -49,5 +50,20 @@ export const channelTools = [
49
50
  },
50
51
  handler: getPlaylistInfoHandler,
51
52
  }),
53
+ defineTool({
54
+ name: 'list_channel_playlists',
55
+ mode: 'all',
56
+ title: 'List YouTube Channel Playlists',
57
+ description: 'List the public playlists a YouTube channel has published, with titles and links. Pass a playlist URL on to fetch_videos or digest_playlist to read what is in it.',
58
+ inputSchema: listChannelPlaylistsSchema,
59
+ outputSchema: listChannelPlaylistsOutputSchema,
60
+ annotations: {
61
+ readOnlyHint: true,
62
+ destructiveHint: false,
63
+ idempotentHint: true,
64
+ openWorldHint: true,
65
+ },
66
+ handler: listChannelPlaylistsHandler,
67
+ }),
52
68
  ];
53
69
  //# sourceMappingURL=channel-tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel-tools.js","sourceRoot":"","sources":["../../src/registry/channel-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AAErC,2CAA2C;AAC3C,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,UAAU,CAAC;QACT,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,0BAA0B;QACjC,WAAW,EACT,mHAAmH;QACrH,WAAW,EAAE,oBAAoB;QACjC,YAAY,EAAE,0BAA0B;QACxC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,qBAAqB;KAC/B,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,8HAA8H;QAChI,WAAW,EAAE,oBAAoB;QACjC,YAAY,EAAE,0BAA0B;QACxC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,qBAAqB;KAC/B,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,+GAA+G;QACjH,WAAW,EAAE,qBAAqB;QAClC,YAAY,EAAE,2BAA2B;QACzC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,sBAAsB;KAChC,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"channel-tools.js","sourceRoot":"","sources":["../../src/registry/channel-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EAChC,2BAA2B,GAC5B,MAAM,oCAAoC,CAAC;AAE5C,2CAA2C;AAC3C,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,UAAU,CAAC;QACT,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,0BAA0B;QACjC,WAAW,EACT,mHAAmH;QACrH,WAAW,EAAE,oBAAoB;QACjC,YAAY,EAAE,0BAA0B;QACxC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,qBAAqB;KAC/B,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,8HAA8H;QAChI,WAAW,EAAE,oBAAoB;QACjC,YAAY,EAAE,0BAA0B;QACxC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,qBAAqB;KAC/B,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,+GAA+G;QACjH,WAAW,EAAE,qBAAqB;QAClC,YAAY,EAAE,2BAA2B;QACzC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,sBAAsB;KAChC,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,wBAAwB;QAC9B,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,gCAAgC;QACvC,WAAW,EACT,oKAAoK;QACtK,WAAW,EAAE,0BAA0B;QACvC,YAAY,EAAE,gCAAgC;QAC9C,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,2BAA2B;KACrC,CAAC;CACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type ToolDefinition } from './types.js';
2
+ /**
3
+ * Exhaustive extraction and the receipts that keep it honest.
4
+ *
5
+ * All stdio-only: they write to the local store, which a channel harvest
6
+ * measures in gigabytes, and no remote caller should be able to fill the
7
+ * operator's disk by naming a channel.
8
+ */
9
+ export declare const harvestTools: ToolDefinition[];
10
+ //# sourceMappingURL=harvest-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harvest-tools.d.ts","sourceRoot":"","sources":["../../src/registry/harvest-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAgC7D;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,EAmGxC,CAAC"}