youtube-knowledge-mcp 2.1.0 → 3.0.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.
- package/README.md +153 -38
- package/dist/brain-schemas.d.ts +10 -10
- package/dist/brain-schemas.d.ts.map +1 -1
- package/dist/brain-schemas.js +0 -4
- package/dist/brain-schemas.js.map +1 -1
- package/dist/harvest-schemas.d.ts +75 -0
- package/dist/harvest-schemas.d.ts.map +1 -0
- package/dist/harvest-schemas.js +106 -0
- package/dist/harvest-schemas.js.map +1 -0
- package/dist/http/app.d.ts +16 -0
- package/dist/http/app.d.ts.map +1 -0
- package/dist/http/app.js +176 -0
- package/dist/http/app.js.map +1 -0
- package/dist/http/auth.d.ts +38 -0
- package/dist/http/auth.d.ts.map +1 -0
- package/dist/http/auth.js +79 -0
- package/dist/http/auth.js.map +1 -0
- package/dist/http/config.d.ts +41 -0
- package/dist/http/config.d.ts.map +1 -0
- package/dist/http/config.js +65 -0
- package/dist/http/config.js.map +1 -0
- package/dist/http/rate-limiter.d.ts +24 -0
- package/dist/http/rate-limiter.d.ts.map +1 -0
- package/dist/http/rate-limiter.js +55 -0
- package/dist/http/rate-limiter.js.map +1 -0
- package/dist/http/sessions.d.ts +34 -0
- package/dist/http/sessions.d.ts.map +1 -0
- package/dist/http/sessions.js +62 -0
- package/dist/http/sessions.js.map +1 -0
- package/dist/http.d.ts +6 -48
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +35 -252
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -517
- package/dist/index.js.map +1 -1
- package/dist/prompts-brain.d.ts +4 -0
- package/dist/prompts-brain.d.ts.map +1 -0
- package/dist/prompts-brain.js +48 -0
- package/dist/prompts-brain.js.map +1 -0
- package/dist/prompts-research.d.ts +4 -0
- package/dist/prompts-research.d.ts.map +1 -0
- package/dist/prompts-research.js +74 -0
- package/dist/prompts-research.js.map +1 -0
- package/dist/prompts-shared.d.ts +13 -0
- package/dist/prompts-shared.d.ts.map +1 -0
- package/dist/prompts-shared.js +7 -0
- package/dist/prompts-shared.js.map +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +5 -100
- package/dist/prompts.js.map +1 -1
- package/dist/registry/brain-tools.d.ts +4 -0
- package/dist/registry/brain-tools.d.ts.map +1 -0
- package/dist/registry/brain-tools.js +104 -0
- package/dist/registry/brain-tools.js.map +1 -0
- package/dist/registry/channel-tools.d.ts +4 -0
- package/dist/registry/channel-tools.d.ts.map +1 -0
- package/dist/registry/channel-tools.js +53 -0
- package/dist/registry/channel-tools.js.map +1 -0
- package/dist/registry/harvest-tools.d.ts +10 -0
- package/dist/registry/harvest-tools.d.ts.map +1 -0
- package/dist/registry/harvest-tools.js +109 -0
- package/dist/registry/harvest-tools.js.map +1 -0
- package/dist/registry/health-tools.d.ts +4 -0
- package/dist/registry/health-tools.d.ts.map +1 -0
- package/dist/registry/health-tools.js +39 -0
- package/dist/registry/health-tools.js.map +1 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +29 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/library-tools.d.ts +4 -0
- package/dist/registry/library-tools.d.ts.map +1 -0
- package/dist/registry/library-tools.js +116 -0
- package/dist/registry/library-tools.js.map +1 -0
- package/dist/registry/media-tools.d.ts +4 -0
- package/dist/registry/media-tools.d.ts.map +1 -0
- package/dist/registry/media-tools.js +100 -0
- package/dist/registry/media-tools.js.map +1 -0
- package/dist/registry/thumbnail-tools.d.ts +7 -0
- package/dist/registry/thumbnail-tools.d.ts.map +1 -0
- package/dist/registry/thumbnail-tools.js +72 -0
- package/dist/registry/thumbnail-tools.js.map +1 -0
- package/dist/registry/transcript-tools.d.ts +4 -0
- package/dist/registry/transcript-tools.d.ts.map +1 -0
- package/dist/registry/transcript-tools.js +68 -0
- package/dist/registry/transcript-tools.js.map +1 -0
- package/dist/registry/types.d.ts +41 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +17 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/registry/video-tools.d.ts +4 -0
- package/dist/registry/video-tools.d.ts.map +1 -0
- package/dist/registry/video-tools.js +101 -0
- package/dist/registry/video-tools.js.map +1 -0
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +13 -10
- package/dist/resources.js.map +1 -1
- package/dist/schemas.d.ts +250 -2
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +61 -0
- package/dist/schemas.js.map +1 -1
- package/dist/thumbnail-resource.d.ts +8 -0
- package/dist/thumbnail-resource.d.ts.map +1 -0
- package/dist/thumbnail-resource.js +38 -0
- package/dist/thumbnail-resource.js.map +1 -0
- package/dist/thumbnail-schemas.d.ts +512 -0
- package/dist/thumbnail-schemas.d.ts.map +1 -0
- package/dist/thumbnail-schemas.js +95 -0
- package/dist/thumbnail-schemas.js.map +1 -0
- package/dist/tools/ask-brain.js +1 -1
- package/dist/tools/ask-brain.js.map +1 -1
- package/dist/tools/batch.js +1 -1
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/brain-info.js +1 -1
- package/dist/tools/brain-info.js.map +1 -1
- package/dist/tools/build-brain.js +1 -1
- package/dist/tools/build-brain.js.map +1 -1
- package/dist/tools/check-health.d.ts +61 -0
- package/dist/tools/check-health.d.ts.map +1 -1
- package/dist/tools/check-health.js +94 -6
- package/dist/tools/check-health.js.map +1 -1
- package/dist/tools/clips.d.ts +9 -41
- package/dist/tools/clips.d.ts.map +1 -1
- package/dist/tools/clips.js +52 -128
- package/dist/tools/clips.js.map +1 -1
- package/dist/tools/fetch-channel-thumbnails.d.ts +179 -0
- package/dist/tools/fetch-channel-thumbnails.d.ts.map +1 -0
- package/dist/tools/fetch-channel-thumbnails.js +123 -0
- package/dist/tools/fetch-channel-thumbnails.js.map +1 -0
- package/dist/tools/fetch-videos.d.ts +18 -4
- package/dist/tools/fetch-videos.d.ts.map +1 -1
- package/dist/tools/fetch-videos.js +64 -20
- package/dist/tools/fetch-videos.js.map +1 -1
- package/dist/tools/frames-subtitles.d.ts +44 -0
- package/dist/tools/frames-subtitles.d.ts.map +1 -0
- package/dist/tools/frames-subtitles.js +104 -0
- package/dist/tools/frames-subtitles.js.map +1 -0
- package/dist/tools/get-channel-info.d.ts +2 -0
- package/dist/tools/get-channel-info.d.ts.map +1 -1
- package/dist/tools/get-channel-info.js +8 -1
- package/dist/tools/get-channel-info.js.map +1 -1
- package/dist/tools/get-comments.d.ts +238 -6
- package/dist/tools/get-comments.d.ts.map +1 -1
- package/dist/tools/get-comments.js +85 -21
- package/dist/tools/get-comments.js.map +1 -1
- package/dist/tools/get-coverage.d.ts +122 -0
- package/dist/tools/get-coverage.d.ts.map +1 -0
- package/dist/tools/get-coverage.js +105 -0
- package/dist/tools/get-coverage.js.map +1 -0
- package/dist/tools/get-playlist-info.d.ts.map +1 -1
- package/dist/tools/get-playlist-info.js +1 -0
- package/dist/tools/get-playlist-info.js.map +1 -1
- package/dist/tools/get-thumbnail.d.ts +38 -0
- package/dist/tools/get-thumbnail.d.ts.map +1 -0
- package/dist/tools/get-thumbnail.js +152 -0
- package/dist/tools/get-thumbnail.js.map +1 -0
- package/dist/tools/get-transcript.d.ts.map +1 -1
- package/dist/tools/get-transcript.js +2 -14
- package/dist/tools/get-transcript.js.map +1 -1
- package/dist/tools/harvest-channel.d.ts +92 -0
- package/dist/tools/harvest-channel.d.ts.map +1 -0
- package/dist/tools/harvest-channel.js +62 -0
- package/dist/tools/harvest-channel.js.map +1 -0
- package/dist/tools/harvest-comments.d.ts +81 -0
- package/dist/tools/harvest-comments.d.ts.map +1 -0
- package/dist/tools/harvest-comments.js +115 -0
- package/dist/tools/harvest-comments.js.map +1 -0
- package/dist/tools/library.d.ts.map +1 -1
- package/dist/tools/library.js +14 -4
- package/dist/tools/library.js.map +1 -1
- package/dist/tools/list-channel-thumbnails.d.ts +235 -0
- package/dist/tools/list-channel-thumbnails.d.ts.map +1 -0
- package/dist/tools/list-channel-thumbnails.js +79 -0
- package/dist/tools/list-channel-thumbnails.js.map +1 -0
- package/dist/tools/list-library.js +1 -1
- package/dist/tools/list-library.js.map +1 -1
- package/dist/tools/prune-harvest.d.ts +59 -0
- package/dist/tools/prune-harvest.d.ts.map +1 -0
- package/dist/tools/prune-harvest.js +108 -0
- package/dist/tools/prune-harvest.js.map +1 -0
- package/dist/tools/query-comments.d.ts +125 -0
- package/dist/tools/query-comments.d.ts.map +1 -0
- package/dist/tools/query-comments.js +106 -0
- package/dist/tools/query-comments.js.map +1 -0
- package/dist/tools/query-videos.d.ts +118 -0
- package/dist/tools/query-videos.d.ts.map +1 -0
- package/dist/tools/query-videos.js +97 -0
- package/dist/tools/query-videos.js.map +1 -0
- package/dist/tools/repair-store.d.ts +34 -0
- package/dist/tools/repair-store.d.ts.map +1 -0
- package/dist/tools/repair-store.js +58 -0
- package/dist/tools/repair-store.js.map +1 -0
- package/dist/tools/save-to-library.d.ts.map +1 -1
- package/dist/tools/save-to-library.js +5 -1
- package/dist/tools/save-to-library.js.map +1 -1
- package/dist/tools/search-channels.d.ts +6 -0
- package/dist/tools/search-channels.d.ts.map +1 -1
- package/dist/tools/search-channels.js +5 -1
- package/dist/tools/search-channels.js.map +1 -1
- package/dist/tools/search-transcript.d.ts.map +1 -1
- package/dist/tools/search-transcript.js +6 -13
- package/dist/tools/search-transcript.js.map +1 -1
- package/dist/tools/search-videos.d.ts +3 -0
- package/dist/tools/search-videos.d.ts.map +1 -1
- package/dist/tools/search-videos.js +1 -1
- package/dist/tools/search-videos.js.map +1 -1
- package/dist/utils/batches.d.ts +15 -0
- package/dist/utils/batches.d.ts.map +1 -0
- package/dist/utils/batches.js +31 -0
- package/dist/utils/batches.js.map +1 -0
- package/dist/utils/brain-build.d.ts.map +1 -1
- package/dist/utils/brain-build.js +1 -12
- package/dist/utils/brain-build.js.map +1 -1
- package/dist/utils/brain-index.d.ts.map +1 -1
- package/dist/utils/brain-index.js +3 -2
- package/dist/utils/brain-index.js.map +1 -1
- package/dist/utils/brain-lock.d.ts +2 -18
- package/dist/utils/brain-lock.d.ts.map +1 -1
- package/dist/utils/brain-lock.js +4 -80
- package/dist/utils/brain-lock.js.map +1 -1
- package/dist/utils/brain-lookup.d.ts +8 -0
- package/dist/utils/brain-lookup.d.ts.map +1 -1
- package/dist/utils/brain-lookup.js +5 -31
- package/dist/utils/brain-lookup.js.map +1 -1
- package/dist/utils/brain-storage.d.ts.map +1 -1
- package/dist/utils/brain-storage.js +5 -5
- package/dist/utils/brain-storage.js.map +1 -1
- package/dist/utils/caption-probe.d.ts +7 -0
- package/dist/utils/caption-probe.d.ts.map +1 -0
- package/dist/utils/caption-probe.js +36 -0
- package/dist/utils/caption-probe.js.map +1 -0
- package/dist/utils/channel-images.d.ts +16 -0
- package/dist/utils/channel-images.d.ts.map +1 -0
- package/dist/utils/channel-images.js +35 -0
- package/dist/utils/channel-images.js.map +1 -0
- package/dist/utils/channel-lookup.d.ts +5 -0
- package/dist/utils/channel-lookup.d.ts.map +1 -0
- package/dist/utils/channel-lookup.js +37 -0
- package/dist/utils/channel-lookup.js.map +1 -0
- package/dist/utils/chapters.d.ts +11 -0
- package/dist/utils/chapters.d.ts.map +1 -0
- package/dist/utils/chapters.js +24 -0
- package/dist/utils/chapters.js.map +1 -0
- package/dist/utils/clips.d.ts.map +1 -1
- package/dist/utils/clips.js +18 -26
- package/dist/utils/clips.js.map +1 -1
- package/dist/utils/comment-store.d.ts +71 -0
- package/dist/utils/comment-store.d.ts.map +1 -0
- package/dist/utils/comment-store.js +129 -0
- package/dist/utils/comment-store.js.map +1 -0
- package/dist/utils/comment-threads.d.ts +51 -0
- package/dist/utils/comment-threads.d.ts.map +1 -0
- package/dist/utils/comment-threads.js +76 -0
- package/dist/utils/comment-threads.js.map +1 -0
- package/dist/utils/coverage-text.d.ts +3 -0
- package/dist/utils/coverage-text.d.ts.map +1 -0
- package/dist/utils/coverage-text.js +62 -0
- package/dist/utils/coverage-text.js.map +1 -0
- package/dist/utils/coverage.d.ts +57 -0
- package/dist/utils/coverage.d.ts.map +1 -0
- package/dist/utils/coverage.js +142 -0
- package/dist/utils/coverage.js.map +1 -0
- package/dist/utils/env.d.ts +26 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +72 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/errors.d.ts +1 -1
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +28 -2
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/file-lock.d.ts +34 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +91 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/flat-listing.d.ts +89 -0
- package/dist/utils/flat-listing.d.ts.map +1 -0
- package/dist/utils/flat-listing.js +68 -0
- package/dist/utils/flat-listing.js.map +1 -0
- package/dist/utils/format.d.ts +18 -4
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +2 -6
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/guard.d.ts +21 -0
- package/dist/utils/guard.d.ts.map +1 -0
- package/dist/utils/guard.js +105 -0
- package/dist/utils/guard.js.map +1 -0
- package/dist/utils/harvest-catalog.d.ts +44 -0
- package/dist/utils/harvest-catalog.d.ts.map +1 -0
- package/dist/utils/harvest-catalog.js +164 -0
- package/dist/utils/harvest-catalog.js.map +1 -0
- package/dist/utils/harvest-lock.d.ts +3 -0
- package/dist/utils/harvest-lock.d.ts.map +1 -0
- package/dist/utils/harvest-lock.js +26 -0
- package/dist/utils/harvest-lock.js.map +1 -0
- package/dist/utils/harvest-receipts.d.ts +14 -0
- package/dist/utils/harvest-receipts.d.ts.map +1 -0
- package/dist/utils/harvest-receipts.js +110 -0
- package/dist/utils/harvest-receipts.js.map +1 -0
- package/dist/utils/image-dimensions.d.ts +19 -0
- package/dist/utils/image-dimensions.d.ts.map +1 -0
- package/dist/utils/image-dimensions.js +93 -0
- package/dist/utils/image-dimensions.js.map +1 -0
- package/dist/utils/image-fetch.d.ts +31 -0
- package/dist/utils/image-fetch.d.ts.map +1 -0
- package/dist/utils/image-fetch.js +141 -0
- package/dist/utils/image-fetch.js.map +1 -0
- package/dist/utils/json-file.d.ts +14 -5
- package/dist/utils/json-file.d.ts.map +1 -1
- package/dist/utils/json-file.js +24 -9
- package/dist/utils/json-file.js.map +1 -1
- package/dist/utils/listing-cursor.d.ts +31 -0
- package/dist/utils/listing-cursor.d.ts.map +1 -0
- package/dist/utils/listing-cursor.js +39 -0
- package/dist/utils/listing-cursor.js.map +1 -0
- package/dist/utils/paths.d.ts +10 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -0
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/pattern.d.ts +30 -0
- package/dist/utils/pattern.d.ts.map +1 -0
- package/dist/utils/pattern.js +130 -0
- package/dist/utils/pattern.js.map +1 -0
- package/dist/utils/pot-preflight.d.ts +53 -0
- package/dist/utils/pot-preflight.d.ts.map +1 -0
- package/dist/utils/pot-preflight.js +146 -0
- package/dist/utils/pot-preflight.js.map +1 -0
- package/dist/utils/search-index.d.ts.map +1 -1
- package/dist/utils/search-index.js +9 -4
- package/dist/utils/search-index.js.map +1 -1
- package/dist/utils/sleep.d.ts +9 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +25 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/storage.js +14 -8
- package/dist/utils/storage.js.map +1 -1
- package/dist/utils/store-health.d.ts +37 -0
- package/dist/utils/store-health.d.ts.map +1 -0
- package/dist/utils/store-health.js +92 -0
- package/dist/utils/store-health.js.map +1 -0
- package/dist/utils/store-migrations.d.ts +33 -0
- package/dist/utils/store-migrations.d.ts.map +1 -0
- package/dist/utils/store-migrations.js +41 -0
- package/dist/utils/store-migrations.js.map +1 -0
- package/dist/utils/store-paths.d.ts +33 -0
- package/dist/utils/store-paths.d.ts.map +1 -0
- package/dist/utils/store-paths.js +48 -0
- package/dist/utils/store-paths.js.map +1 -0
- package/dist/utils/store-rows.d.ts +22 -0
- package/dist/utils/store-rows.d.ts.map +1 -0
- package/dist/utils/store-rows.js +62 -0
- package/dist/utils/store-rows.js.map +1 -0
- package/dist/utils/store-schema.d.ts +16 -0
- package/dist/utils/store-schema.d.ts.map +1 -0
- package/dist/utils/store-schema.js +168 -0
- package/dist/utils/store-schema.js.map +1 -0
- package/dist/utils/store.d.ts +34 -0
- package/dist/utils/store.d.ts.map +1 -0
- package/dist/utils/store.js +157 -0
- package/dist/utils/store.js.map +1 -0
- package/dist/utils/subtitles.d.ts +7 -0
- package/dist/utils/subtitles.d.ts.map +1 -0
- package/dist/utils/subtitles.js +30 -0
- package/dist/utils/subtitles.js.map +1 -0
- package/dist/utils/thumbnail-entry.d.ts +19 -0
- package/dist/utils/thumbnail-entry.d.ts.map +1 -0
- package/dist/utils/thumbnail-entry.js +119 -0
- package/dist/utils/thumbnail-entry.js.map +1 -0
- package/dist/utils/thumbnail-fetch.d.ts +37 -0
- package/dist/utils/thumbnail-fetch.d.ts.map +1 -0
- package/dist/utils/thumbnail-fetch.js +89 -0
- package/dist/utils/thumbnail-fetch.js.map +1 -0
- package/dist/utils/thumbnail-ladder.d.ts +44 -0
- package/dist/utils/thumbnail-ladder.d.ts.map +1 -0
- package/dist/utils/thumbnail-ladder.js +68 -0
- package/dist/utils/thumbnail-ladder.js.map +1 -0
- package/dist/utils/thumbnail-listing.d.ts +16 -0
- package/dist/utils/thumbnail-listing.d.ts.map +1 -0
- package/dist/utils/thumbnail-listing.js +26 -0
- package/dist/utils/thumbnail-listing.js.map +1 -0
- package/dist/utils/thumbnail-paths.d.ts +20 -0
- package/dist/utils/thumbnail-paths.d.ts.map +1 -0
- package/dist/utils/thumbnail-paths.js +35 -0
- package/dist/utils/thumbnail-paths.js.map +1 -0
- package/dist/utils/thumbnail-store.d.ts +19 -0
- package/dist/utils/thumbnail-store.d.ts.map +1 -0
- package/dist/utils/thumbnail-store.js +125 -0
- package/dist/utils/thumbnail-store.js.map +1 -0
- package/dist/utils/transcript-cache.d.ts +20 -0
- package/dist/utils/transcript-cache.d.ts.map +1 -0
- package/dist/utils/transcript-cache.js +127 -0
- package/dist/utils/transcript-cache.js.map +1 -0
- package/dist/utils/transcript-search.d.ts +20 -0
- package/dist/utils/transcript-search.d.ts.map +1 -0
- package/dist/utils/transcript-search.js +35 -0
- package/dist/utils/transcript-search.js.map +1 -0
- package/dist/utils/transcript.d.ts +10 -31
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +2 -64
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/validate-youtube.d.ts +35 -0
- package/dist/utils/validate-youtube.d.ts.map +1 -0
- package/dist/utils/validate-youtube.js +87 -0
- package/dist/utils/validate-youtube.js.map +1 -0
- package/dist/utils/validate.d.ts +11 -4
- package/dist/utils/validate.d.ts.map +1 -1
- package/dist/utils/validate.js +43 -36
- package/dist/utils/validate.js.map +1 -1
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +19 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/utils/video-stats-cache.d.ts +16 -0
- package/dist/utils/video-stats-cache.d.ts.map +1 -0
- package/dist/utils/video-stats-cache.js +81 -0
- package/dist/utils/video-stats-cache.js.map +1 -0
- package/dist/utils/video-stats.d.ts +186 -0
- package/dist/utils/video-stats.d.ts.map +1 -0
- package/dist/utils/video-stats.js +168 -0
- package/dist/utils/video-stats.js.map +1 -0
- package/dist/utils/video-store.d.ts +69 -0
- package/dist/utils/video-store.d.ts.map +1 -0
- package/dist/utils/video-store.js +77 -0
- package/dist/utils/video-store.js.map +1 -0
- package/dist/utils/youtube-channel.d.ts +51 -0
- package/dist/utils/youtube-channel.d.ts.map +1 -0
- package/dist/utils/youtube-channel.js +91 -0
- package/dist/utils/youtube-channel.js.map +1 -0
- package/dist/utils/youtube-download.d.ts +27 -0
- package/dist/utils/youtube-download.d.ts.map +1 -0
- package/dist/utils/youtube-download.js +118 -0
- package/dist/utils/youtube-download.js.map +1 -0
- package/dist/utils/youtube-schemas.d.ts +492 -0
- package/dist/utils/youtube-schemas.d.ts.map +1 -0
- package/dist/utils/youtube-schemas.js +148 -0
- package/dist/utils/youtube-schemas.js.map +1 -0
- package/dist/utils/youtube-search.d.ts +14 -0
- package/dist/utils/youtube-search.d.ts.map +1 -0
- package/dist/utils/youtube-search.js +39 -0
- package/dist/utils/youtube-search.js.map +1 -0
- package/dist/utils/youtube-url.d.ts +25 -0
- package/dist/utils/youtube-url.d.ts.map +1 -0
- package/dist/utils/youtube-url.js +75 -0
- package/dist/utils/youtube-url.js.map +1 -0
- package/dist/utils/youtube-video.d.ts +68 -0
- package/dist/utils/youtube-video.d.ts.map +1 -0
- package/dist/utils/youtube-video.js +110 -0
- package/dist/utils/youtube-video.js.map +1 -0
- package/dist/utils/youtube.d.ts +10 -122
- package/dist/utils/youtube.d.ts.map +1 -1
- package/dist/utils/youtube.js +11 -486
- package/dist/utils/youtube.js.map +1 -1
- package/dist/utils/ytdlp-env.d.ts +33 -0
- package/dist/utils/ytdlp-env.d.ts.map +1 -0
- package/dist/utils/ytdlp-env.js +121 -0
- package/dist/utils/ytdlp-env.js.map +1 -0
- package/dist/utils/ytdlp-limiter.d.ts +27 -0
- package/dist/utils/ytdlp-limiter.d.ts.map +1 -0
- package/dist/utils/ytdlp-limiter.js +85 -0
- package/dist/utils/ytdlp-limiter.js.map +1 -0
- package/dist/utils/ytdlp-pacer.d.ts +64 -0
- package/dist/utils/ytdlp-pacer.d.ts.map +1 -0
- package/dist/utils/ytdlp-pacer.js +165 -0
- package/dist/utils/ytdlp-pacer.js.map +1 -0
- package/dist/utils/ytdlp-parse.d.ts +13 -0
- package/dist/utils/ytdlp-parse.d.ts.map +1 -0
- package/dist/utils/ytdlp-parse.js +48 -0
- package/dist/utils/ytdlp-parse.js.map +1 -0
- package/dist/utils/ytdlp-stream.d.ts +32 -0
- package/dist/utils/ytdlp-stream.d.ts.map +1 -0
- package/dist/utils/ytdlp-stream.js +61 -0
- package/dist/utils/ytdlp-stream.js.map +1 -0
- package/dist/utils/ytdlp.d.ts +23 -18
- package/dist/utils/ytdlp.d.ts.map +1 -1
- package/dist/utils/ytdlp.js +56 -134
- package/dist/utils/ytdlp.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/youtube-knowledge-mcp)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://nodejs.org/)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
6
|
[](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.
|
|
@@ -18,6 +18,7 @@ Supports both **local** (stdio) and **remote** (Streamable HTTP) transports.
|
|
|
18
18
|
- **Search** videos and channels by keyword
|
|
19
19
|
- **Fetch** videos from a playlist or channel
|
|
20
20
|
- **Video, channel and playlist metadata**, chapters, and top comments
|
|
21
|
+
- **Thumbnails**: look at any video's thumbnail or a channel's avatar or banner as an image, or save every thumbnail of a channel to disk
|
|
21
22
|
- **Transcripts with timestamps**, sliced by time range or chapter, and capped so a
|
|
22
23
|
three-hour video cannot flood your context
|
|
23
24
|
- **Search inside a transcript** and get back `?t=` links that open the video at
|
|
@@ -39,6 +40,19 @@ Supports both **local** (stdio) and **remote** (Streamable HTTP) transports.
|
|
|
39
40
|
- **Read them back**, and **search across all of them** with full-text ranking
|
|
40
41
|
- **Tag, retag and delete**
|
|
41
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
|
+
|
|
42
56
|
**Build a brain for a channel** (local mode)
|
|
43
57
|
|
|
44
58
|
- **Read a whole channel** into a searchable corpus of timestamped passages, in
|
|
@@ -50,18 +64,25 @@ Supports both **local** (stdio) and **remote** (Streamable HTTP) transports.
|
|
|
50
64
|
speaking rate, and the phrases it repeats across videos
|
|
51
65
|
- **Keep a written profile** beside the corpus, grounded in passages you can cite
|
|
52
66
|
|
|
67
|
+
**Study a channel's thumbnails** (local mode)
|
|
68
|
+
|
|
69
|
+
- **Save every thumbnail** of a channel, plus its avatar and banner, resumably, at the largest size YouTube serves, with each image's real pixel size recorded
|
|
70
|
+
|
|
53
71
|
**Built to stay working**
|
|
54
72
|
|
|
55
73
|
- WebVTT parsed by the W3C reference implementation, not a hand-written matcher
|
|
56
74
|
- Typed, actionable errors — "no captions in en, try: fr, es, de" rather than a
|
|
57
75
|
wall of yt-dlp stderr
|
|
58
|
-
- Timeouts,
|
|
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
|
|
59
78
|
- `check_health` diagnoses missing or outdated yt-dlp and ffmpeg
|
|
79
|
+
- Bearer auth, a loopback default bind, an allowlist on every URL and image host, and typed error codes on every failure
|
|
60
80
|
- Structured output on every tool, plus MCP resources, prompts and completions
|
|
81
|
+
- An end-to-end suite runs the built server against real yt-dlp over both transports every week
|
|
61
82
|
|
|
62
83
|
## Prerequisites
|
|
63
84
|
|
|
64
|
-
- Node.js 22+
|
|
85
|
+
- Node.js 22.13+ — the version where `node:sqlite`, which the harvest store uses, is available without a flag
|
|
65
86
|
- [yt-dlp](https://github.com/yt-dlp/yt-dlp#installation) — required by every tool.
|
|
66
87
|
`brew install yt-dlp` (macOS) or `pip install -U yt-dlp`
|
|
67
88
|
- [ffmpeg](https://ffmpeg.org/) — required for downloads, clip extraction and frame
|
|
@@ -154,7 +175,11 @@ npm run build
|
|
|
154
175
|
npm run start:http
|
|
155
176
|
```
|
|
156
177
|
|
|
157
|
-
The server listens on `PORT` (default 3000).
|
|
178
|
+
The server listens on `127.0.0.1:PORT` (default 3000). To reach it from another
|
|
179
|
+
machine set `MCP_BIND_HOST=0.0.0.0` together with `MCP_AUTH_TOKEN`; the server
|
|
180
|
+
refuses to start exposed and unauthenticated unless you also set
|
|
181
|
+
`MCP_ALLOW_UNAUTHENTICATED=true`. Behind a reverse proxy, set `MCP_TRUST_PROXY`
|
|
182
|
+
to the number of hops and `MCP_PUBLIC_URL` to the address clients use.
|
|
158
183
|
|
|
159
184
|
#### Docker
|
|
160
185
|
|
|
@@ -210,7 +235,7 @@ a cold start. Any paid plan removes that.
|
|
|
210
235
|
|
|
211
236
|
## MCP Tools
|
|
212
237
|
|
|
213
|
-
|
|
238
|
+
44 tools. The 15 read-only ones work over both transports; the 29 that touch
|
|
214
239
|
your filesystem are registered only in local (stdio) mode, so a remote
|
|
215
240
|
deployment cannot reach the host's disk.
|
|
216
241
|
|
|
@@ -220,18 +245,19 @@ available for this video. Call get_transcript again with one of: fr, es, de.`
|
|
|
220
245
|
|
|
221
246
|
### Discovery — remote + local
|
|
222
247
|
|
|
223
|
-
| Tool | Key parameters
|
|
224
|
-
| ------------------- |
|
|
225
|
-
| `search_videos` | `query`, `limit`
|
|
226
|
-
| `search_channels` | `query`, `limit`
|
|
227
|
-
| `fetch_videos` | `url`, `limit`
|
|
228
|
-
| `get_video_info` | `video`
|
|
229
|
-
| `get_channel_info` | `channel`
|
|
230
|
-
| `get_playlist_info` | `url`
|
|
231
|
-
| `get_chapters` | `video`
|
|
232
|
-
| `get_comments` | `video`, `limit` |
|
|
233
|
-
| `list_formats` | `video`
|
|
234
|
-
| `
|
|
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 and banner |
|
|
255
|
+
| `get_playlist_info` | `url` | Title, channel, video count, last updated |
|
|
256
|
+
| `get_chapters` | `video` | Chapter titles with start/end times and deep links |
|
|
257
|
+
| `get_comments` | `video`, `limit`, `includeReplies`, `sort` | Comments with replies and a completeness receipt saying how many of the video's comments this is |
|
|
258
|
+
| `list_formats` | `video` | Available formats grouped by video+audio, video-only, audio-only |
|
|
259
|
+
| `get_thumbnail` | `video`, `channel`, `image`, `quality` | A video thumbnail, channel avatar or banner as an image, with its real size |
|
|
260
|
+
| `check_health` | — | yt-dlp and ffmpeg status, versions, staleness warnings, and which session options are set |
|
|
235
261
|
|
|
236
262
|
### Transcripts — remote + local
|
|
237
263
|
|
|
@@ -274,6 +300,35 @@ keyframe-aligned cut. All of these require ffmpeg.
|
|
|
274
300
|
| `delete_library_item` | `videoId`, `contentType` | What was deleted |
|
|
275
301
|
| `rebuild_library_index` | — | Number of notes reindexed |
|
|
276
302
|
|
|
303
|
+
### Exhaustive harvest — local only
|
|
304
|
+
|
|
305
|
+
Extraction that stores what it reads, and proves what it holds. Every tool here
|
|
306
|
+
returns a **completeness receipt**: `complete` is true only when the server can
|
|
307
|
+
prove it has everything in scope, and a consumer must not describe the data as a
|
|
308
|
+
full history while it is false.
|
|
309
|
+
|
|
310
|
+
| Tool | Key parameters | Returns |
|
|
311
|
+
| ------------------ | ---------------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
312
|
+
| `harvest_channel` | `channel`, `maxVideos` | Every video across all tabs, catalogued, with a receipt |
|
|
313
|
+
| `harvest_comments` | `video`, `maxComments`, `sort`, `maxRepliesPerThread` | Comments and replies stored locally, with a receipt |
|
|
314
|
+
| `get_coverage` | `scope`, `incompleteOnly`, `verify`, `limit`, `offset` | What the server can prove it holds, and what it cannot |
|
|
315
|
+
| `query_comments` | `video`, `channel`, `match`, `author`, `threadOf`, `order`, `limit` | Full-text search over stored comments, with real pagination |
|
|
316
|
+
| `query_videos` | `channel`, `match`, `since`, `until`, `withComments`, `order`, `limit` | The catalogued videos, filtered and sorted |
|
|
317
|
+
| `prune_harvest` | `channel`, `video`, `author`, `scope`, `confirm`, `vacuum` | What was removed from the store |
|
|
318
|
+
| `repair_store` | `confirm` | Moves a damaged store aside and starts a fresh one |
|
|
319
|
+
|
|
320
|
+
`get_coverage` never contacts YouTube, so it is cheap enough to call before
|
|
321
|
+
making any claim about the data. Check `anyIncomplete` first.
|
|
322
|
+
|
|
323
|
+
There is no cursor for comments: YouTube exposes none for a live read, so
|
|
324
|
+
`harvest_comments` cannot page. To get more, run it again with a larger
|
|
325
|
+
`maxComments` — rows are upserted on the comment id, so a re-run costs requests
|
|
326
|
+
and never data.
|
|
327
|
+
|
|
328
|
+
`prune_harvest` exists because the store holds personal data at scale: display
|
|
329
|
+
names, channel ids and free-text opinions from people who never used this tool.
|
|
330
|
+
The `author` filter is the per-person erasure path.
|
|
331
|
+
|
|
277
332
|
### Channel brains — local only
|
|
278
333
|
|
|
279
334
|
| Tool | Key parameters | Returns |
|
|
@@ -289,6 +344,24 @@ keyframe-aligned cut. All of these require ffmpeg.
|
|
|
289
344
|
channel from what is already on disk, so they work offline and cost nothing to
|
|
290
345
|
call.
|
|
291
346
|
|
|
347
|
+
### Channel thumbnails — local only
|
|
348
|
+
|
|
349
|
+
| Tool | Key parameters | Returns |
|
|
350
|
+
| --------------------------- | -------------------------------------------- | --------------------------------------------------------- |
|
|
351
|
+
| `fetch_channel_thumbnails` | `channel`, `maxVideos`, `tabs`, `quality` | Every thumbnail saved to disk, plus the avatar and banner |
|
|
352
|
+
| `list_channel_thumbnails` | `channel`, `tab`, `state`, `limit`, `offset` | Saved entries with paths and decoded sizes |
|
|
353
|
+
| `delete_channel_thumbnails` | `channel` | What was removed |
|
|
354
|
+
|
|
355
|
+
One yt-dlp listing per tab, then the images from YouTube's image hosts
|
|
356
|
+
directly, so a five-hundred-video channel costs a handful of listings and not
|
|
357
|
+
five hundred extractions. For each video the fetch tries the largest image
|
|
358
|
+
YouTube serves (`maxresdefault`, 1280 wide where it exists) and keeps it only if
|
|
359
|
+
it decodes wider than the image the listing offered; otherwise it keeps the
|
|
360
|
+
listed image, and failing that the small `hqdefault`. Every width and height in
|
|
361
|
+
the manifest was decoded from the saved bytes, never read off a URL. Shorts are
|
|
362
|
+
listed with portrait thumbnails and saved under `shorts/`. The run is resumable:
|
|
363
|
+
interrupt it and call again, and only what is missing or truncated is fetched.
|
|
364
|
+
|
|
292
365
|
A brain holds one caption language; pass `language` to read another, and build a
|
|
293
366
|
separate brain per language.
|
|
294
367
|
|
|
@@ -309,16 +382,18 @@ skipped forever as already done.
|
|
|
309
382
|
|
|
310
383
|
Reusable workflows your client can invoke directly: `summarize_video`,
|
|
311
384
|
`extract_skill`, `compare_videos`, `research_topic`, `channel_deep_dive`,
|
|
312
|
-
`clip_from_quote` (find a phrase, then cut the clip around it),
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
385
|
+
`clip_from_quote` (find a phrase, then cut the clip around it),
|
|
386
|
+
`study_thumbnails` (save a channel's thumbnails, look at a sample, describe
|
|
387
|
+
what recurs), and — local only — `review_library`, `create_brain` (build a
|
|
388
|
+
channel's corpus, then write its profile from it) and `ask_creator` (answer a
|
|
389
|
+
question strictly from a brain, with citations).
|
|
316
390
|
|
|
317
391
|
## Resources
|
|
318
392
|
|
|
319
393
|
- `youtube://transcript/{videoId}` — a timestamped transcript, fetched and cached on first read
|
|
320
394
|
- `youtube://library/{videoId}/{summary|skill}` — a saved note (local only, and enumerable)
|
|
321
395
|
- `youtube://brain/{channelId}/{manifest|profile}` — what a channel brain covers, or the profile written from it (local only, and enumerable)
|
|
396
|
+
- `youtube://thumbnails/{channelId}/manifest` — what `fetch_channel_thumbnails` saved for a channel (local only, and enumerable)
|
|
322
397
|
|
|
323
398
|
## Error codes
|
|
324
399
|
|
|
@@ -334,25 +409,51 @@ them, each prefixed with a code and followed by a next step.
|
|
|
334
409
|
| `RATE_LIMITED`, `TIMEOUT` | Transient; retried automatically with backoff before surfacing |
|
|
335
410
|
| `YTDLP_MISSING`, `FFMPEG_MISSING`, `YTDLP_FAILED` | A tooling problem; the message says how to fix it |
|
|
336
411
|
| `INVALID_INPUT` | A bad argument, caught before any network call |
|
|
412
|
+
| `BOT_CHECK` | YouTube asked this address to sign in; set the cookie settings below |
|
|
413
|
+
| `FETCH_FAILED` | An image could not be downloaded from YouTube's image hosts |
|
|
337
414
|
| `CANCELLED` | The client cancelled the request |
|
|
338
415
|
|
|
339
416
|
## Environment variables
|
|
340
417
|
|
|
341
418
|
All optional.
|
|
342
419
|
|
|
343
|
-
| Variable
|
|
344
|
-
|
|
|
345
|
-
| `MCP_AUTH_TOKEN`
|
|
346
|
-
| `MCP_ALLOWED_HOSTS`
|
|
347
|
-
| `MCP_ALLOWED_ORIGINS`
|
|
348
|
-
| `MCP_BIND_HOST`
|
|
349
|
-
| `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
| `
|
|
420
|
+
| Variable | Default | Purpose |
|
|
421
|
+
| ---------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
422
|
+
| `MCP_AUTH_TOKEN` | unset | Require this bearer token on the HTTP transport. **Set this if you expose the server beyond localhost.** |
|
|
423
|
+
| `MCP_ALLOWED_HOSTS` | unset | Comma-separated Host allowlist; enables DNS-rebinding protection |
|
|
424
|
+
| `MCP_ALLOWED_ORIGINS` | unset | Comma-separated Origin allowlist |
|
|
425
|
+
| `MCP_BIND_HOST` | `127.0.0.1` | Interface to bind. The Docker image sets `0.0.0.0`. A non-loopback bind refuses to start without `MCP_AUTH_TOKEN` unless `MCP_ALLOW_UNAUTHENTICATED=true` |
|
|
426
|
+
| `MCP_ALLOW_UNAUTHENTICATED` | `false` | Explicit consent to listen on a network interface with no token |
|
|
427
|
+
| `MCP_TRUST_PROXY` | `false` | `true`, `false`, or the number of reverse-proxy hops whose `X-Forwarded-*` headers to believe. Off, forwarded headers are ignored for rate limiting and URLs |
|
|
428
|
+
| `MCP_PUBLIC_URL` | unset | The URL clients reach the server at; used in the OAuth metadata it publishes instead of the request's Host |
|
|
429
|
+
| `MCP_MAX_BODY_BYTES` | `1048576` | Largest request body accepted |
|
|
430
|
+
| `MCP_MODE` | unset | `http` selects the HTTP transport when no `--http` flag is given |
|
|
431
|
+
| `PORT` | `3000` | HTTP port. The Docker image sets `10000`; Render and similar platforms inject their own |
|
|
432
|
+
| `MCP_RATE_LIMIT` | `60` | Requests per window, per client |
|
|
433
|
+
| `MCP_RATE_WINDOW_MS` | `60000` | Rate-limit window |
|
|
434
|
+
| `MCP_SESSION_IDLE_MS` | `1800000` | Close HTTP sessions idle this long |
|
|
435
|
+
| `MCP_MAX_SESSIONS` | `1000` | Reject new sessions past this many |
|
|
436
|
+
| `YOUTUBE_MCP_MAX_CONCURRENCY` | `3` | Concurrent yt-dlp processes |
|
|
437
|
+
| `YOUTUBE_MCP_TRANSCRIPT_TTL_MS` | 30 days | Transcript cache lifetime |
|
|
438
|
+
| `YOUTUBE_MCP_STATS_TTL_MS` | 1 day | Per-video stats cache lifetime |
|
|
439
|
+
| `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 |
|
|
440
|
+
| `YOUTUBE_MCP_COOKIES_FILE` | unset | A Netscape-format cookies file inside your home directory, as an alternative to a browser |
|
|
441
|
+
| `YOUTUBE_MCP_PROXY` | unset | An `http`, `https`, `socks4` or `socks5` proxy URL for yt-dlp |
|
|
442
|
+
| `YOUTUBE_MCP_SLEEP_REQUESTS_S` | unset | Seconds yt-dlp sleeps between its own requests, to stay under YouTube's limits |
|
|
443
|
+
|
|
444
|
+
### Signed-in content
|
|
445
|
+
|
|
446
|
+
Some videos need a signed-in session — age-restricted, members-only, private
|
|
447
|
+
ones you have access to — and YouTube sometimes asks an address to prove it is
|
|
448
|
+
not a bot before serving any video at all. Those failures arrive as
|
|
449
|
+
`LOGIN_REQUIRED`, `AGE_GATED` or `BOT_CHECK`, and each names the fix: set
|
|
450
|
+
`YOUTUBE_MCP_COOKIES_FROM_BROWSER` to a browser you are signed in with, or
|
|
451
|
+
`YOUTUBE_MCP_COOKIES_FILE` to a cookies file, and restart the server.
|
|
452
|
+
|
|
453
|
+
Cookies are your account. Use them in local (stdio) mode, keep a cookies file
|
|
454
|
+
readable by you alone, and know that content read this way may be personal.
|
|
455
|
+
The server validates both settings at boot, never logs the file's path or
|
|
456
|
+
contents, and never surfaces yt-dlp's output.
|
|
356
457
|
|
|
357
458
|
## Library Storage
|
|
358
459
|
|
|
@@ -372,6 +473,13 @@ Content is stored in `~/.youtube-knowledge/`:
|
|
|
372
473
|
│ ├── manifest.json # What the brain covers, and where a build stopped
|
|
373
474
|
│ ├── chunks.json # The timestamped passages
|
|
374
475
|
│ └── profile.md # The written account, if one was saved
|
|
476
|
+
├── thumbnails/ # Saved channel thumbnails
|
|
477
|
+
│ └── {channel_id}/
|
|
478
|
+
│ ├── manifest.json # Every image, its decoded size, where it is
|
|
479
|
+
│ ├── channel/ # avatar.* and banner.*
|
|
480
|
+
│ ├── videos/ # {video_id}.jpg (or .png / .webp)
|
|
481
|
+
│ ├── shorts/
|
|
482
|
+
│ └── streams/
|
|
375
483
|
├── downloads/ # Full downloads
|
|
376
484
|
├── clips/ # Extracted clips
|
|
377
485
|
├── frames/ # Captured stills
|
|
@@ -469,6 +577,11 @@ client over an in-memory transport, exercises the library against a real
|
|
|
469
577
|
temporary filesystem, and snapshots the tool manifest so any change to the
|
|
470
578
|
public surface shows up as a reviewable diff.
|
|
471
579
|
|
|
580
|
+
An end-to-end lane (`E2E=1 npm run test:e2e`) drives the built server through
|
|
581
|
+
real MCP clients over both transports against real yt-dlp and the real network,
|
|
582
|
+
in an isolated temporary home. It runs weekly in CI and on every release before
|
|
583
|
+
anything is published; see CONTRIBUTING.md.
|
|
584
|
+
|
|
472
585
|
## Development
|
|
473
586
|
|
|
474
587
|
```bash
|
|
@@ -480,7 +593,7 @@ npm run start:http # Run server (HTTP)
|
|
|
480
593
|
npm run validate # Typecheck + lint + format check + test
|
|
481
594
|
```
|
|
482
595
|
|
|
483
|
-
CI runs the same gate on Node 22 and 24 for every push and pull request,
|
|
596
|
+
CI runs the same gate on Node 22.22, 22 and 24 for every push and pull request,
|
|
484
597
|
then boots the built server as a real MCP client to verify the manifest.
|
|
485
598
|
|
|
486
599
|
## Contributing
|
|
@@ -490,9 +603,11 @@ project layout, coding standards, and how to add a tool.
|
|
|
490
603
|
|
|
491
604
|
## Security
|
|
492
605
|
|
|
493
|
-
The HTTP transport
|
|
494
|
-
|
|
495
|
-
|
|
606
|
+
The HTTP transport binds loopback and refuses to listen on a network interface
|
|
607
|
+
without `MCP_AUTH_TOKEN`. Caller-supplied URLs must be on a YouTube host before
|
|
608
|
+
anything is handed to yt-dlp, every yt-dlp target follows a `--` terminator, and
|
|
609
|
+
ids are validated before they become paths. See [SECURITY.md](SECURITY.md) for
|
|
610
|
+
the deployment checklist and how to report a vulnerability.
|
|
496
611
|
|
|
497
612
|
## License
|
|
498
613
|
|
package/dist/brain-schemas.d.ts
CHANGED
|
@@ -226,6 +226,8 @@ export declare const brainManifestSchema: z.ZodObject<{
|
|
|
226
226
|
subscriberCount: z.ZodNumber;
|
|
227
227
|
channelUrl: z.ZodString;
|
|
228
228
|
description: z.ZodString;
|
|
229
|
+
avatarUrl: z.ZodOptional<z.ZodString>;
|
|
230
|
+
bannerUrl: z.ZodOptional<z.ZodString>;
|
|
229
231
|
}, "strip", z.ZodTypeAny, {
|
|
230
232
|
description: string;
|
|
231
233
|
name: string;
|
|
@@ -233,6 +235,8 @@ export declare const brainManifestSchema: z.ZodObject<{
|
|
|
233
235
|
handle: string;
|
|
234
236
|
subscriberCount: number;
|
|
235
237
|
channelUrl: string;
|
|
238
|
+
avatarUrl?: string | undefined;
|
|
239
|
+
bannerUrl?: string | undefined;
|
|
236
240
|
}, {
|
|
237
241
|
description: string;
|
|
238
242
|
name: string;
|
|
@@ -240,6 +244,8 @@ export declare const brainManifestSchema: z.ZodObject<{
|
|
|
240
244
|
handle: string;
|
|
241
245
|
subscriberCount: number;
|
|
242
246
|
channelUrl: string;
|
|
247
|
+
avatarUrl?: string | undefined;
|
|
248
|
+
bannerUrl?: string | undefined;
|
|
243
249
|
}>;
|
|
244
250
|
/**
|
|
245
251
|
* A brain is built from one caption language. Defaulted rather than required
|
|
@@ -345,6 +351,8 @@ export declare const brainManifestSchema: z.ZodObject<{
|
|
|
345
351
|
handle: string;
|
|
346
352
|
subscriberCount: number;
|
|
347
353
|
channelUrl: string;
|
|
354
|
+
avatarUrl?: string | undefined;
|
|
355
|
+
bannerUrl?: string | undefined;
|
|
348
356
|
};
|
|
349
357
|
version: number;
|
|
350
358
|
videos: Record<string, {
|
|
@@ -391,6 +399,8 @@ export declare const brainManifestSchema: z.ZodObject<{
|
|
|
391
399
|
handle: string;
|
|
392
400
|
subscriberCount: number;
|
|
393
401
|
channelUrl: string;
|
|
402
|
+
avatarUrl?: string | undefined;
|
|
403
|
+
bannerUrl?: string | undefined;
|
|
394
404
|
};
|
|
395
405
|
version: number;
|
|
396
406
|
videos: Record<string, unknown>;
|
|
@@ -489,14 +499,4 @@ export declare const brainSummarySchema: z.ZodObject<{
|
|
|
489
499
|
updatedAt: string;
|
|
490
500
|
hasProfile: boolean;
|
|
491
501
|
}>;
|
|
492
|
-
export declare const brainLockSchema: z.ZodObject<{
|
|
493
|
-
pid: z.ZodNumber;
|
|
494
|
-
startedAt: z.ZodString;
|
|
495
|
-
}, "strip", z.ZodTypeAny, {
|
|
496
|
-
pid: number;
|
|
497
|
-
startedAt: string;
|
|
498
|
-
}, {
|
|
499
|
-
pid: number;
|
|
500
|
-
startedAt: string;
|
|
501
|
-
}>;
|
|
502
502
|
//# sourceMappingURL=brain-schemas.d.ts.map
|
|
@@ -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
|
|
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"}
|
package/dist/brain-schemas.js
CHANGED
|
@@ -106,8 +106,4 @@ export const brainSummarySchema = z.object({
|
|
|
106
106
|
indexedCount: z.number().int(),
|
|
107
107
|
chunkCount: z.number().int(),
|
|
108
108
|
});
|
|
109
|
-
export const brainLockSchema = z.object({
|
|
110
|
-
pid: z.number().int(),
|
|
111
|
-
startedAt: z.string(),
|
|
112
|
-
});
|
|
113
109
|
//# sourceMappingURL=brain-schemas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brain-schemas.js","sourceRoot":"","sources":["../src/brain-schemas.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"brain-schemas.js","sourceRoot":"","sources":["../src/brain-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEhE;;;;;;GAMG;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IACvF,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,KAAK,EAAE,CAAC;SACL,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;SACjE,QAAQ,CACP,4JAA4J,CAC7J;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CAC5E,CAAC,CAAC;AAIH,uDAAuD;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACzB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;CAClC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IAC9E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;CAC9B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;IACrC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;CACzB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;IAC9F,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;IAC3F,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC9B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC7B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC5B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC5B,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE;IAChC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC;IACnD,gBAAgB,EAAE,CAAC;SAChB,KAAK,CAAC,iBAAiB,CAAC;SACxB,QAAQ,EAAE;SACV,QAAQ,CACP,0QAA0Q,CAC3Q;CACJ,CAAC,CAAC;AAIH,4BAA4B;AAC5B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACzB,OAAO,EAAE,iBAAiB;IAC1B;;;OAGG;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,MAAM,EAAE,aAAa,CAAC,qBAAqB,CAAC;IAC5C,KAAK,EAAE,gBAAgB;CACxB,CAAC,CAAC;AAIH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;CACrE,CAAC,CAAC;AAIH,8BAA8B;AAC9B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;IACvB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC5B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;CAC7B,CAAC,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"]>;
|
|
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"]>>;
|
|
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
|
+
have: number;
|
|
43
|
+
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
44
|
+
targetId: string;
|
|
45
|
+
complete: boolean;
|
|
46
|
+
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
47
|
+
source: string;
|
|
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" | undefined;
|
|
53
|
+
staleAfter?: string | undefined;
|
|
54
|
+
limitApplied?: number | undefined;
|
|
55
|
+
sortApplied?: "top" | "new" | undefined;
|
|
56
|
+
resumeToken?: string | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
have: number;
|
|
59
|
+
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
60
|
+
targetId: string;
|
|
61
|
+
complete: boolean;
|
|
62
|
+
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
63
|
+
source: string;
|
|
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" | 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,oFAI/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,106 @@
|
|
|
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
|
+
export const coverageSchema = z.object({
|
|
55
|
+
scope: harvestScopeSchema,
|
|
56
|
+
targetId: z.string().describe('Channel id for a catalog, video id for details or comments'),
|
|
57
|
+
complete: z
|
|
58
|
+
.boolean()
|
|
59
|
+
.describe('True ONLY when this server can prove it holds every item in scope. False means the ' +
|
|
60
|
+
'data is a SAMPLE. A consumer must not describe it as a full history while this is false.'),
|
|
61
|
+
reason: completenessReasonSchema.describe('Why complete is what it is. Always present, including when complete is true.'),
|
|
62
|
+
have: z
|
|
63
|
+
.number()
|
|
64
|
+
.int()
|
|
65
|
+
.nonnegative()
|
|
66
|
+
.describe('Items this store actually holds for this target, counted from the store.'),
|
|
67
|
+
expected: z
|
|
68
|
+
.number()
|
|
69
|
+
.int()
|
|
70
|
+
.nonnegative()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('The total the SOURCE states. Absent when the source states none — never inferred, ' +
|
|
73
|
+
'never copied from have. Absent with complete:false means "unknown how much is missing".'),
|
|
74
|
+
expectedSource: expectedSourceSchema
|
|
75
|
+
.optional()
|
|
76
|
+
.describe('Where expected came from. Absent if and only if expected is absent.'),
|
|
77
|
+
ranToExhaustion: z
|
|
78
|
+
.boolean()
|
|
79
|
+
.optional()
|
|
80
|
+
.describe("Whether the source's own iteration finished rather than being cut off. Necessary for " +
|
|
81
|
+
'completeness but not sufficient: a cap also ends iteration.'),
|
|
82
|
+
source: z.string().describe('The exact extraction path, including tool version and flags.'),
|
|
83
|
+
harvestedAt: z.string().describe('ISO-8601 of the last item written for this target'),
|
|
84
|
+
staleAfter: z
|
|
85
|
+
.string()
|
|
86
|
+
.optional()
|
|
87
|
+
.describe('ISO-8601 after which this should be re-checked. Comments accrue, so a complete ' +
|
|
88
|
+
'receipt goes stale without becoming wrong.'),
|
|
89
|
+
limitApplied: z
|
|
90
|
+
.number()
|
|
91
|
+
.int()
|
|
92
|
+
.positive()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe('The cap the caller asked for. Present if and only if one was applied.'),
|
|
95
|
+
sortApplied: z
|
|
96
|
+
.enum(['top', 'new'])
|
|
97
|
+
.optional()
|
|
98
|
+
.describe('Ordering the source applied. A capped "top" harvest is a BIASED PREFIX of a stream, ' +
|
|
99
|
+
'not a random sample.'),
|
|
100
|
+
resumeToken: z
|
|
101
|
+
.string()
|
|
102
|
+
.optional()
|
|
103
|
+
.describe('Opaque. Pass to the same tool to continue. Absent if and only if complete.'),
|
|
104
|
+
note: z.string().optional(),
|
|
105
|
+
});
|
|
106
|
+
//# 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;CACnB,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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Express } from 'express';
|
|
2
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { type HttpConfig } from './config.js';
|
|
4
|
+
import type { RateLimiter } from './rate-limiter.js';
|
|
5
|
+
import type { SessionStore } from './sessions.js';
|
|
6
|
+
/** The Express application: routes, authentication and rate limiting. */
|
|
7
|
+
export interface AppDependencies {
|
|
8
|
+
createServer: (mode: 'http') => McpServer;
|
|
9
|
+
sessions: SessionStore;
|
|
10
|
+
limiter: RateLimiter;
|
|
11
|
+
/** The bound port, known only once listening; read lazily for that reason. */
|
|
12
|
+
port: () => number;
|
|
13
|
+
startedAt: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildApp(config: HttpConfig, deps: AppDependencies): Express;
|
|
16
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/http/app.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAmC,MAAM,SAAS,CAAC;AAOxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYzE,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,yEAAyE;AAEzE,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IAC1C,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAqK3E"}
|