youtube-knowledge-mcp 2.0.2 → 2.2.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 +166 -33
- package/dist/brain-schemas.d.ts +502 -0
- package/dist/brain-schemas.d.ts.map +1 -0
- package/dist/brain-schemas.js +109 -0
- package/dist/brain-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 -431
- 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 -58
- 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/health-tools.d.ts +4 -0
- package/dist/registry/health-tools.d.ts.map +1 -0
- package/dist/registry/health-tools.js +21 -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 +27 -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 +75 -6
- package/dist/resources.js.map +1 -1
- package/dist/schemas.d.ts +74 -54
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +30 -4
- 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.d.ts +62 -0
- package/dist/tools/ask-brain.d.ts.map +1 -0
- package/dist/tools/ask-brain.js +70 -0
- package/dist/tools/ask-brain.js.map +1 -0
- package/dist/tools/batch.d.ts +10 -10
- package/dist/tools/batch.js +3 -3
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/brain-info.d.ts +180 -0
- package/dist/tools/brain-info.d.ts.map +1 -0
- package/dist/tools/brain-info.js +108 -0
- package/dist/tools/brain-info.js.map +1 -0
- package/dist/tools/build-brain.d.ts +120 -0
- package/dist/tools/build-brain.d.ts.map +1 -0
- package/dist/tools/build-brain.js +123 -0
- package/dist/tools/build-brain.js.map +1 -0
- package/dist/tools/check-health.d.ts +2 -0
- package/dist/tools/check-health.d.ts.map +1 -1
- package/dist/tools/check-health.js +9 -0
- package/dist/tools/check-health.js.map +1 -1
- package/dist/tools/clips.d.ts +13 -45
- 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 +11 -8
- package/dist/tools/fetch-videos.d.ts.map +1 -1
- package/dist/tools/fetch-videos.js +3 -0
- 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-chapters.d.ts +2 -2
- package/dist/tools/get-comments.d.ts +2 -2
- 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 +2 -2
- 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/library.d.ts +9 -7
- package/dist/tools/library.d.ts.map +1 -1
- package/dist/tools/library.js +23 -7
- 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.d.ts +4 -4
- package/dist/tools/manage-brain.d.ts +39 -0
- package/dist/tools/manage-brain.d.ts.map +1 -0
- package/dist/tools/manage-brain.js +53 -0
- package/dist/tools/manage-brain.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 +10 -4
- package/dist/tools/search-channels.d.ts.map +1 -1
- package/dist/tools/search-transcript.d.ts +2 -2
- 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 +11 -8
- package/dist/tools/search-videos.d.ts.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 +40 -0
- package/dist/utils/brain-build.d.ts.map +1 -0
- package/dist/utils/brain-build.js +200 -0
- package/dist/utils/brain-build.js.map +1 -0
- package/dist/utils/brain-chunks.d.ts +33 -0
- package/dist/utils/brain-chunks.d.ts.map +1 -0
- package/dist/utils/brain-chunks.js +87 -0
- package/dist/utils/brain-chunks.js.map +1 -0
- package/dist/utils/brain-index.d.ts +27 -0
- package/dist/utils/brain-index.d.ts.map +1 -0
- package/dist/utils/brain-index.js +101 -0
- package/dist/utils/brain-index.js.map +1 -0
- package/dist/utils/brain-ingest.d.ts +57 -0
- package/dist/utils/brain-ingest.d.ts.map +1 -0
- package/dist/utils/brain-ingest.js +127 -0
- package/dist/utils/brain-ingest.js.map +1 -0
- package/dist/utils/brain-lock.d.ts +4 -0
- package/dist/utils/brain-lock.d.ts.map +1 -0
- package/dist/utils/brain-lock.js +17 -0
- package/dist/utils/brain-lock.js.map +1 -0
- package/dist/utils/brain-lookup.d.ts +11 -0
- package/dist/utils/brain-lookup.d.ts.map +1 -0
- package/dist/utils/brain-lookup.js +36 -0
- package/dist/utils/brain-lookup.js.map +1 -0
- package/dist/utils/brain-paths.d.ts +19 -0
- package/dist/utils/brain-paths.d.ts.map +1 -0
- package/dist/utils/brain-paths.js +34 -0
- package/dist/utils/brain-paths.js.map +1 -0
- package/dist/utils/brain-phrases.d.ts +31 -0
- package/dist/utils/brain-phrases.d.ts.map +1 -0
- package/dist/utils/brain-phrases.js +116 -0
- package/dist/utils/brain-phrases.js.map +1 -0
- package/dist/utils/brain-stats.d.ts +25 -0
- package/dist/utils/brain-stats.d.ts.map +1 -0
- package/dist/utils/brain-stats.js +64 -0
- package/dist/utils/brain-stats.js.map +1 -0
- package/dist/utils/brain-storage.d.ts +28 -0
- package/dist/utils/brain-storage.d.ts.map +1 -0
- package/dist/utils/brain-storage.js +87 -0
- package/dist/utils/brain-storage.js.map +1 -0
- 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 +22 -30
- package/dist/utils/clips.js.map +1 -1
- 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 +20 -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 +1 -3
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +1 -5
- 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/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 +45 -0
- package/dist/utils/json-file.d.ts.map +1 -0
- package/dist/utils/json-file.js +60 -0
- package/dist/utils/json-file.js.map +1 -0
- package/dist/utils/paths.d.ts +19 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +27 -0
- package/dist/utils/paths.js.map +1 -0
- 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/search-index.d.ts +22 -7
- package/dist/utils/search-index.d.ts.map +1 -1
- package/dist/utils/search-index.js +26 -8
- package/dist/utils/search-index.js.map +1 -1
- package/dist/utils/storage.d.ts +14 -44
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/storage.js +47 -84
- package/dist/utils/storage.js.map +1 -1
- 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 +14 -34
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +5 -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 -3
- package/dist/utils/validate.d.ts.map +1 -1
- package/dist/utils/validate.js +43 -18
- 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/youtube-channel.d.ts +44 -0
- package/dist/utils/youtube-channel.d.ts.map +1 -0
- package/dist/utils/youtube-channel.js +61 -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 +394 -0
- package/dist/utils/youtube-schemas.d.ts.map +1 -0
- package/dist/utils/youtube-schemas.js +118 -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 +47 -0
- package/dist/utils/youtube-video.d.ts.map +1 -0
- package/dist/utils/youtube-video.js +98 -0
- package/dist/utils/youtube-video.js.map +1 -0
- package/dist/utils/youtube.d.ts +13 -111
- package/dist/utils/youtube.d.ts.map +1 -1
- package/dist/utils/youtube.js +11 -480
- 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 +24 -0
- package/dist/utils/ytdlp-limiter.d.ts.map +1 -0
- package/dist/utils/ytdlp-limiter.js +69 -0
- package/dist/utils/ytdlp-limiter.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.d.ts +13 -18
- package/dist/utils/ytdlp.d.ts.map +1 -1
- package/dist/utils/ytdlp.js +21 -110
- package/dist/utils/ytdlp.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-tools.js","sourceRoot":"","sources":["../../src/registry/library-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-tools.d.ts","sourceRoot":"","sources":["../../src/registry/media-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AA0B7D,6EAA6E;AAC7E,eAAO,MAAM,UAAU,EAAE,cAAc,EAmGtC,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { defineTool } from './types.js';
|
|
2
|
+
import { extractClipSchema, extractClipOutputSchema, extractClipHandler, extractAudioClipSchema, extractAudioClipOutputSchema, extractAudioClipHandler, extractClipsSchema, extractClipsOutputSchema, extractClipsHandler, } from '../tools/clips.js';
|
|
3
|
+
import { downloadVideoSchema, downloadVideoOutputSchema, downloadVideoHandler, } from '../tools/download-video.js';
|
|
4
|
+
import { extractFrameSchema, extractFrameOutputSchema, extractFrameHandler, exportSubtitlesSchema, exportSubtitlesOutputSchema, exportSubtitlesHandler, } from '../tools/frames-subtitles.js';
|
|
5
|
+
/** Clips, stills, subtitles and downloads. Local only: these write files. */
|
|
6
|
+
export const mediaTools = [
|
|
7
|
+
defineTool({
|
|
8
|
+
name: 'extract_clip',
|
|
9
|
+
mode: 'stdio',
|
|
10
|
+
title: 'Extract a Video Clip',
|
|
11
|
+
description: 'Cut a time range out of a YouTube video without downloading the whole thing. Give start and end, or a chapter name. Pair with search_transcript to find the moment first. Requires ffmpeg.',
|
|
12
|
+
inputSchema: extractClipSchema,
|
|
13
|
+
outputSchema: extractClipOutputSchema,
|
|
14
|
+
annotations: {
|
|
15
|
+
readOnlyHint: false,
|
|
16
|
+
destructiveHint: false,
|
|
17
|
+
idempotentHint: true,
|
|
18
|
+
openWorldHint: true,
|
|
19
|
+
},
|
|
20
|
+
handler: extractClipHandler,
|
|
21
|
+
}),
|
|
22
|
+
defineTool({
|
|
23
|
+
name: 'extract_audio_clip',
|
|
24
|
+
mode: 'stdio',
|
|
25
|
+
title: 'Extract an Audio Clip',
|
|
26
|
+
description: 'Cut a time range out of a video as audio only, in an editor-friendly format (mp3, m4a, wav, flac, opus). Use for podcast pulls and voice-over sourcing. Requires ffmpeg.',
|
|
27
|
+
inputSchema: extractAudioClipSchema,
|
|
28
|
+
outputSchema: extractAudioClipOutputSchema,
|
|
29
|
+
annotations: {
|
|
30
|
+
readOnlyHint: false,
|
|
31
|
+
destructiveHint: false,
|
|
32
|
+
idempotentHint: true,
|
|
33
|
+
openWorldHint: true,
|
|
34
|
+
},
|
|
35
|
+
handler: extractAudioClipHandler,
|
|
36
|
+
}),
|
|
37
|
+
defineTool({
|
|
38
|
+
name: 'extract_clips',
|
|
39
|
+
mode: 'stdio',
|
|
40
|
+
title: 'Extract Several Clips',
|
|
41
|
+
description: 'Cut several time ranges out of one video in a single call. A range that fails is reported individually rather than losing the clips that succeeded. Requires ffmpeg.',
|
|
42
|
+
inputSchema: extractClipsSchema,
|
|
43
|
+
outputSchema: extractClipsOutputSchema,
|
|
44
|
+
annotations: {
|
|
45
|
+
readOnlyHint: false,
|
|
46
|
+
destructiveHint: false,
|
|
47
|
+
idempotentHint: true,
|
|
48
|
+
openWorldHint: true,
|
|
49
|
+
},
|
|
50
|
+
handler: extractClipsHandler,
|
|
51
|
+
}),
|
|
52
|
+
defineTool({
|
|
53
|
+
name: 'extract_frame',
|
|
54
|
+
mode: 'stdio',
|
|
55
|
+
title: 'Capture a Frame',
|
|
56
|
+
description: 'Capture a single still image from a video at a given timestamp, without downloading the file. Use for thumbnails and reference frames. Requires ffmpeg.',
|
|
57
|
+
inputSchema: extractFrameSchema,
|
|
58
|
+
outputSchema: extractFrameOutputSchema,
|
|
59
|
+
annotations: {
|
|
60
|
+
readOnlyHint: false,
|
|
61
|
+
destructiveHint: false,
|
|
62
|
+
idempotentHint: true,
|
|
63
|
+
openWorldHint: true,
|
|
64
|
+
},
|
|
65
|
+
handler: extractFrameHandler,
|
|
66
|
+
}),
|
|
67
|
+
defineTool({
|
|
68
|
+
name: 'export_subtitles',
|
|
69
|
+
mode: 'stdio',
|
|
70
|
+
title: 'Export Subtitles',
|
|
71
|
+
description: 'Write a video transcript to disk as SRT, WebVTT or plain text, ready to import into a video editor such as Premiere, Resolve or CapCut.',
|
|
72
|
+
inputSchema: exportSubtitlesSchema,
|
|
73
|
+
outputSchema: exportSubtitlesOutputSchema,
|
|
74
|
+
annotations: {
|
|
75
|
+
readOnlyHint: false,
|
|
76
|
+
destructiveHint: false,
|
|
77
|
+
idempotentHint: true,
|
|
78
|
+
openWorldHint: true,
|
|
79
|
+
},
|
|
80
|
+
handler: exportSubtitlesHandler,
|
|
81
|
+
}),
|
|
82
|
+
defineTool({
|
|
83
|
+
name: 'download_video',
|
|
84
|
+
mode: 'stdio',
|
|
85
|
+
title: 'Download YouTube Video',
|
|
86
|
+
description: 'Download a YouTube video to local disk. Use the quality parameter for automatic format selection with smart fallbacks, or formatId for a specific format from list_formats. Returns the downloaded file path, title, and format details.',
|
|
87
|
+
inputSchema: downloadVideoSchema,
|
|
88
|
+
outputSchema: downloadVideoOutputSchema,
|
|
89
|
+
annotations: {
|
|
90
|
+
readOnlyHint: false,
|
|
91
|
+
destructiveHint: false,
|
|
92
|
+
// Writes to a deterministic path and overwrites, exactly like the
|
|
93
|
+
// extract_* tools; repeating the call leaves the same state.
|
|
94
|
+
idempotentHint: true,
|
|
95
|
+
openWorldHint: true,
|
|
96
|
+
},
|
|
97
|
+
handler: downloadVideoHandler,
|
|
98
|
+
}),
|
|
99
|
+
];
|
|
100
|
+
//# sourceMappingURL=media-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-tools.js","sourceRoot":"","sources":["../../src/registry/media-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ToolDefinition } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Thumbnails. Looking at one is remote-safe; saving a channel's worth is local
|
|
4
|
+
* only, for the same reason as the brains.
|
|
5
|
+
*/
|
|
6
|
+
export declare const thumbnailTools: ToolDefinition[];
|
|
7
|
+
//# sourceMappingURL=thumbnail-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thumbnail-tools.d.ts","sourceRoot":"","sources":["../../src/registry/thumbnail-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAoB7D;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,EAkE1C,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { defineTool } from './types.js';
|
|
2
|
+
import { fetchChannelThumbnailsSchema, fetchChannelThumbnailsOutputSchema, fetchChannelThumbnailsHandler, } from '../tools/fetch-channel-thumbnails.js';
|
|
3
|
+
import { listChannelThumbnailsSchema, listChannelThumbnailsOutputSchema, listChannelThumbnailsHandler, deleteChannelThumbnailsSchema, deleteChannelThumbnailsOutputSchema, deleteChannelThumbnailsHandler, } from '../tools/list-channel-thumbnails.js';
|
|
4
|
+
import { getThumbnailSchema, getThumbnailOutputSchema, getThumbnailHandler, } from '../tools/get-thumbnail.js';
|
|
5
|
+
/**
|
|
6
|
+
* Thumbnails. Looking at one is remote-safe; saving a channel's worth is local
|
|
7
|
+
* only, for the same reason as the brains.
|
|
8
|
+
*/
|
|
9
|
+
export const thumbnailTools = [
|
|
10
|
+
defineTool({
|
|
11
|
+
name: 'get_thumbnail',
|
|
12
|
+
mode: 'all',
|
|
13
|
+
title: 'Look at a Thumbnail',
|
|
14
|
+
description: "Return a video's thumbnail, or a channel's avatar or banner, as an image you can look at, with its real pixel size. Tries the largest image YouTube serves and falls back to smaller ones. Locally, an image saved by fetch_channel_thumbnails is served from disk.",
|
|
15
|
+
inputSchema: getThumbnailSchema,
|
|
16
|
+
outputSchema: getThumbnailOutputSchema,
|
|
17
|
+
annotations: {
|
|
18
|
+
readOnlyHint: true,
|
|
19
|
+
destructiveHint: false,
|
|
20
|
+
idempotentHint: true,
|
|
21
|
+
openWorldHint: true,
|
|
22
|
+
},
|
|
23
|
+
handler: (args) => getThumbnailHandler(args, { store: false }),
|
|
24
|
+
stdioHandler: (args) => getThumbnailHandler(args, { store: true }),
|
|
25
|
+
}),
|
|
26
|
+
defineTool({
|
|
27
|
+
name: 'fetch_channel_thumbnails',
|
|
28
|
+
mode: 'stdio',
|
|
29
|
+
title: "Save a Channel's Thumbnails",
|
|
30
|
+
description: "Save every video thumbnail of a channel, plus its avatar and banner, under ~/.youtube-knowledge/thumbnails. One listing per tab, then the images from YouTube's image hosts directly, largest available first; each saved image is recorded with the size actually decoded from it. Safe to interrupt and call again: images already on disk are kept, missing ones fetched. Choose tabs to include shorts and streams.",
|
|
31
|
+
inputSchema: fetchChannelThumbnailsSchema,
|
|
32
|
+
outputSchema: fetchChannelThumbnailsOutputSchema,
|
|
33
|
+
annotations: {
|
|
34
|
+
readOnlyHint: false,
|
|
35
|
+
destructiveHint: false,
|
|
36
|
+
idempotentHint: true,
|
|
37
|
+
openWorldHint: true,
|
|
38
|
+
},
|
|
39
|
+
handler: fetchChannelThumbnailsHandler,
|
|
40
|
+
}),
|
|
41
|
+
defineTool({
|
|
42
|
+
name: 'list_channel_thumbnails',
|
|
43
|
+
mode: 'stdio',
|
|
44
|
+
title: "List a Channel's Saved Thumbnails",
|
|
45
|
+
description: 'List the thumbnails saved for a channel: each file path, its decoded size and which image variant it is, plus the avatar and banner. Works offline from the saved manifest.',
|
|
46
|
+
inputSchema: listChannelThumbnailsSchema,
|
|
47
|
+
outputSchema: listChannelThumbnailsOutputSchema,
|
|
48
|
+
annotations: {
|
|
49
|
+
readOnlyHint: true,
|
|
50
|
+
destructiveHint: false,
|
|
51
|
+
idempotentHint: true,
|
|
52
|
+
openWorldHint: false,
|
|
53
|
+
},
|
|
54
|
+
handler: listChannelThumbnailsHandler,
|
|
55
|
+
}),
|
|
56
|
+
defineTool({
|
|
57
|
+
name: 'delete_channel_thumbnails',
|
|
58
|
+
mode: 'stdio',
|
|
59
|
+
title: "Delete a Channel's Saved Thumbnails",
|
|
60
|
+
description: 'Permanently delete every thumbnail saved for a channel, with its manifest. Use this to start over, for example to fetch again at a different quality.',
|
|
61
|
+
inputSchema: deleteChannelThumbnailsSchema,
|
|
62
|
+
outputSchema: deleteChannelThumbnailsOutputSchema,
|
|
63
|
+
annotations: {
|
|
64
|
+
readOnlyHint: false,
|
|
65
|
+
destructiveHint: true,
|
|
66
|
+
idempotentHint: true,
|
|
67
|
+
openWorldHint: false,
|
|
68
|
+
},
|
|
69
|
+
handler: deleteChannelThumbnailsHandler,
|
|
70
|
+
}),
|
|
71
|
+
];
|
|
72
|
+
//# sourceMappingURL=thumbnail-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thumbnail-tools.js","sourceRoot":"","sources":["../../src/registry/thumbnail-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,4BAA4B,EAC5B,kCAAkC,EAClC,6BAA6B,GAC9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,EACjC,4BAA4B,EAC5B,6BAA6B,EAC7B,mCAAmC,EACnC,8BAA8B,GAC/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C,UAAU,CAAC;QACT,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,qQAAqQ;QACvQ,WAAW,EAAE,kBAAkB;QAC/B,YAAY,EAAE,wBAAwB;QACtC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC9D,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;KACnE,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,0BAA0B;QAChC,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,6BAA6B;QACpC,WAAW,EACT,yZAAyZ;QAC3Z,WAAW,EAAE,4BAA4B;QACzC,YAAY,EAAE,kCAAkC;QAChD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,6BAA6B;KACvC,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,yBAAyB;QAC/B,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EACT,6KAA6K;QAC/K,WAAW,EAAE,2BAA2B;QACxC,YAAY,EAAE,iCAAiC;QAC/C,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;QACD,OAAO,EAAE,4BAA4B;KACtC,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,2BAA2B;QACjC,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EACT,uJAAuJ;QACzJ,WAAW,EAAE,6BAA6B;QAC1C,YAAY,EAAE,mCAAmC;QACjD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;QACD,OAAO,EAAE,8BAA8B;KACxC,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-tools.d.ts","sourceRoot":"","sources":["../../src/registry/transcript-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAoB7D,6EAA6E;AAC7E,eAAO,MAAM,eAAe,EAAE,cAAc,EAiE3C,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { defineTool } from './types.js';
|
|
2
|
+
import { getTranscriptsSchema, getTranscriptsOutputSchema, getTranscriptsHandler, digestPlaylistSchema, digestPlaylistOutputSchema, digestPlaylistHandler, } from '../tools/batch.js';
|
|
3
|
+
import { getTranscriptSchema, getTranscriptOutputSchema, getTranscriptHandler, } from '../tools/get-transcript.js';
|
|
4
|
+
import { searchTranscriptSchema, searchTranscriptOutputSchema, searchTranscriptHandler, } from '../tools/search-transcript.js';
|
|
5
|
+
/** Reading and searching transcripts, singly and in batches. Remote-safe. */
|
|
6
|
+
export const transcriptTools = [
|
|
7
|
+
defineTool({
|
|
8
|
+
name: 'get_transcript',
|
|
9
|
+
mode: 'all',
|
|
10
|
+
title: 'Get YouTube Video Transcript',
|
|
11
|
+
description: 'Extract the full transcript from a YouTube video. Supports auto-generated and manual captions. Returns plain text with word count and detected language. Results are cached locally.',
|
|
12
|
+
inputSchema: getTranscriptSchema,
|
|
13
|
+
outputSchema: getTranscriptOutputSchema,
|
|
14
|
+
annotations: {
|
|
15
|
+
readOnlyHint: true,
|
|
16
|
+
destructiveHint: false,
|
|
17
|
+
idempotentHint: true,
|
|
18
|
+
openWorldHint: true,
|
|
19
|
+
},
|
|
20
|
+
handler: getTranscriptHandler,
|
|
21
|
+
}),
|
|
22
|
+
defineTool({
|
|
23
|
+
name: 'search_transcript',
|
|
24
|
+
mode: 'all',
|
|
25
|
+
title: 'Search Inside a Transcript',
|
|
26
|
+
description: 'Find a phrase or pattern inside a video transcript and return each match with its timestamp and a link that opens the video at that moment. Use this instead of reading a whole transcript when you need to locate or cite a specific moment.',
|
|
27
|
+
inputSchema: searchTranscriptSchema,
|
|
28
|
+
outputSchema: searchTranscriptOutputSchema,
|
|
29
|
+
annotations: {
|
|
30
|
+
readOnlyHint: true,
|
|
31
|
+
destructiveHint: false,
|
|
32
|
+
idempotentHint: true,
|
|
33
|
+
openWorldHint: true,
|
|
34
|
+
},
|
|
35
|
+
handler: searchTranscriptHandler,
|
|
36
|
+
}),
|
|
37
|
+
defineTool({
|
|
38
|
+
name: 'get_transcripts',
|
|
39
|
+
mode: 'all',
|
|
40
|
+
title: 'Get Transcripts for Several Videos',
|
|
41
|
+
description: 'Fetch transcripts for up to 25 videos in one call, each capped so the batch cannot flood the context. Videos that have no captions are reported individually rather than failing the whole call.',
|
|
42
|
+
inputSchema: getTranscriptsSchema,
|
|
43
|
+
outputSchema: getTranscriptsOutputSchema,
|
|
44
|
+
annotations: {
|
|
45
|
+
readOnlyHint: true,
|
|
46
|
+
destructiveHint: false,
|
|
47
|
+
idempotentHint: true,
|
|
48
|
+
openWorldHint: true,
|
|
49
|
+
},
|
|
50
|
+
handler: getTranscriptsHandler,
|
|
51
|
+
}),
|
|
52
|
+
defineTool({
|
|
53
|
+
name: 'digest_playlist',
|
|
54
|
+
mode: 'all',
|
|
55
|
+
title: 'Digest a Playlist or Channel',
|
|
56
|
+
description: 'Summarize a playlist or channel in one call: per-video metadata, chapter markers, and optionally transcript word counts. Use this to survey a body of content before deciding what to read in full.',
|
|
57
|
+
inputSchema: digestPlaylistSchema,
|
|
58
|
+
outputSchema: digestPlaylistOutputSchema,
|
|
59
|
+
annotations: {
|
|
60
|
+
readOnlyHint: true,
|
|
61
|
+
destructiveHint: false,
|
|
62
|
+
idempotentHint: true,
|
|
63
|
+
openWorldHint: true,
|
|
64
|
+
},
|
|
65
|
+
handler: digestPlaylistHandler,
|
|
66
|
+
}),
|
|
67
|
+
];
|
|
68
|
+
//# sourceMappingURL=transcript-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-tools.js","sourceRoot":"","sources":["../../src/registry/transcript-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,+BAA+B,CAAC;AAEvC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC/C,UAAU,CAAC;QACT,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,8BAA8B;QACrC,WAAW,EACT,sLAAsL;QACxL,WAAW,EAAE,mBAAmB;QAChC,YAAY,EAAE,yBAAyB;QACvC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,oBAAoB;KAC9B,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,4BAA4B;QACnC,WAAW,EACT,+OAA+O;QACjP,WAAW,EAAE,sBAAsB;QACnC,YAAY,EAAE,4BAA4B;QAC1C,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,uBAAuB;KACjC,CAAC;IACF,UAAU,CAAC;QACT,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,oCAAoC;QAC3C,WAAW,EACT,kMAAkM;QACpM,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,8BAA8B;QACrC,WAAW,EACT,qMAAqM;QACvM,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;CACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ZodRawShape } from 'zod';
|
|
2
|
+
import type { McpServer, ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* A tool as one declarative record.
|
|
6
|
+
*
|
|
7
|
+
* `createServer` used to be twenty-seven near-identical `registerTool` calls
|
|
8
|
+
* spread over seven hundred lines, and the only thing that varied between them
|
|
9
|
+
* was data. Declaring each tool as data keeps the registration in one loop,
|
|
10
|
+
* lets a test enumerate every tool without booting a server, and makes the
|
|
11
|
+
* transport gate — local-only tools never registered over HTTP — a field
|
|
12
|
+
* rather than an `if` block a new tool can land on the wrong side of.
|
|
13
|
+
*/
|
|
14
|
+
export type ToolMode = 'all' | 'stdio';
|
|
15
|
+
export interface ToolDefinition {
|
|
16
|
+
name: string;
|
|
17
|
+
mode: ToolMode;
|
|
18
|
+
register: (server: McpServer, transport: 'stdio' | 'http') => void;
|
|
19
|
+
}
|
|
20
|
+
export interface ToolSpec<In extends ZodRawShape, Out extends ZodRawShape> {
|
|
21
|
+
name: string;
|
|
22
|
+
mode: ToolMode;
|
|
23
|
+
title: string;
|
|
24
|
+
description: string;
|
|
25
|
+
inputSchema: In;
|
|
26
|
+
outputSchema: Out;
|
|
27
|
+
/** Every hint is required: a client decides what to ask before running on them. */
|
|
28
|
+
annotations: Required<Pick<ToolAnnotations, 'readOnlyHint' | 'destructiveHint' | 'idempotentHint' | 'openWorldHint'>>;
|
|
29
|
+
handler: ToolCallback<In>;
|
|
30
|
+
/**
|
|
31
|
+
* A handler to use on stdio instead of `handler`, for the rare tool whose
|
|
32
|
+
* remote and local behaviour differ (a local one may read the user's disk).
|
|
33
|
+
*/
|
|
34
|
+
stdioHandler?: ToolCallback<In>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Capture the schema/handler pairing generically, then hand back a record the
|
|
38
|
+
* registry can hold in one array without any of them needing a cast.
|
|
39
|
+
*/
|
|
40
|
+
export declare function defineTool<In extends ZodRawShape, Out extends ZodRawShape>(spec: ToolSpec<In, Out>): ToolDefinition;
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/registry/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAG1E;;;;;;;;;GASG;AAEH,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,WAAW;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,EAAE,CAAC;IAChB,YAAY,EAAE,GAAG,CAAC;IAClB,mFAAmF;IACnF,WAAW,EAAE,QAAQ,CACnB,IAAI,CAAC,eAAe,EAAE,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,eAAe,CAAC,CAC/F,CAAC;IACF,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,WAAW,EACxE,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,GACtB,cAAc,CAchB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { guarded } from '../utils/guard.js';
|
|
2
|
+
/**
|
|
3
|
+
* Capture the schema/handler pairing generically, then hand back a record the
|
|
4
|
+
* registry can hold in one array without any of them needing a cast.
|
|
5
|
+
*/
|
|
6
|
+
export function defineTool(spec) {
|
|
7
|
+
const { name, mode, title, description, inputSchema, outputSchema, annotations } = spec;
|
|
8
|
+
return {
|
|
9
|
+
name,
|
|
10
|
+
mode,
|
|
11
|
+
register: (server, transport) => {
|
|
12
|
+
const handler = transport === 'stdio' ? (spec.stdioHandler ?? spec.handler) : spec.handler;
|
|
13
|
+
server.registerTool(name, { title, description, inputSchema, outputSchema, annotations }, guarded(handler));
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/registry/types.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAwC5C;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,IAAuB;IAEvB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACxF,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE;YAC9B,MAAM,OAAO,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3F,MAAM,CAAC,YAAY,CACjB,IAAI,EACJ,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,EAC9D,OAAO,CAAC,OAAO,CAAC,CACjB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video-tools.d.ts","sourceRoot":"","sources":["../../src/registry/video-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAgC7D,iHAAiH;AACjH,eAAO,MAAM,UAAU,EAAE,cAAc,EAiGtC,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { defineTool } from './types.js';
|
|
2
|
+
import { listFormatsSchema, listFormatsOutputSchema, listFormatsHandler, } from '../tools/download-video.js';
|
|
3
|
+
import { fetchVideosSchema, fetchVideosOutputSchema, fetchVideosHandler, } from '../tools/fetch-videos.js';
|
|
4
|
+
import { getChaptersSchema, getChaptersOutputSchema, getChaptersHandler, } from '../tools/get-chapters.js';
|
|
5
|
+
import { getCommentsSchema, getCommentsOutputSchema, getCommentsHandler, } from '../tools/get-comments.js';
|
|
6
|
+
import { getVideoInfoSchema, getVideoInfoOutputSchema, getVideoInfoHandler, } from '../tools/get-video-info.js';
|
|
7
|
+
import { searchVideosSchema, searchVideosOutputSchema, searchVideosHandler, } from '../tools/search-videos.js';
|
|
8
|
+
/** Finding videos and reading what YouTube knows about one. Remote-safe: nothing here touches the filesystem. */
|
|
9
|
+
export const videoTools = [
|
|
10
|
+
defineTool({
|
|
11
|
+
name: 'search_videos',
|
|
12
|
+
mode: 'all',
|
|
13
|
+
title: 'Search YouTube Videos',
|
|
14
|
+
description: 'Search YouTube for videos by keyword or phrase. Returns video IDs, titles, durations, channels, view counts, and URLs. Results sorted by relevance.',
|
|
15
|
+
inputSchema: searchVideosSchema,
|
|
16
|
+
outputSchema: searchVideosOutputSchema,
|
|
17
|
+
annotations: {
|
|
18
|
+
readOnlyHint: true,
|
|
19
|
+
destructiveHint: false,
|
|
20
|
+
idempotentHint: true,
|
|
21
|
+
openWorldHint: true,
|
|
22
|
+
},
|
|
23
|
+
handler: searchVideosHandler,
|
|
24
|
+
}),
|
|
25
|
+
defineTool({
|
|
26
|
+
name: 'fetch_videos',
|
|
27
|
+
mode: 'all',
|
|
28
|
+
title: 'Fetch YouTube Videos',
|
|
29
|
+
description: 'List videos from a YouTube playlist or channel. Returns video IDs, titles, durations, upload dates, and URLs. Sorted by playlist or channel order.',
|
|
30
|
+
inputSchema: fetchVideosSchema,
|
|
31
|
+
outputSchema: fetchVideosOutputSchema,
|
|
32
|
+
annotations: {
|
|
33
|
+
readOnlyHint: true,
|
|
34
|
+
destructiveHint: false,
|
|
35
|
+
idempotentHint: true,
|
|
36
|
+
openWorldHint: true,
|
|
37
|
+
},
|
|
38
|
+
handler: fetchVideosHandler,
|
|
39
|
+
}),
|
|
40
|
+
defineTool({
|
|
41
|
+
name: 'get_video_info',
|
|
42
|
+
mode: 'all',
|
|
43
|
+
title: 'Get YouTube Video Info',
|
|
44
|
+
description: 'Get detailed metadata for a single YouTube video. Returns title, channel, duration, upload date, view count, like count, comment count, description, tags, and thumbnail URL.',
|
|
45
|
+
inputSchema: getVideoInfoSchema,
|
|
46
|
+
outputSchema: getVideoInfoOutputSchema,
|
|
47
|
+
annotations: {
|
|
48
|
+
readOnlyHint: true,
|
|
49
|
+
destructiveHint: false,
|
|
50
|
+
idempotentHint: true,
|
|
51
|
+
openWorldHint: true,
|
|
52
|
+
},
|
|
53
|
+
handler: getVideoInfoHandler,
|
|
54
|
+
}),
|
|
55
|
+
defineTool({
|
|
56
|
+
name: 'get_chapters',
|
|
57
|
+
mode: 'all',
|
|
58
|
+
title: 'Get YouTube Video Chapters',
|
|
59
|
+
description: 'Extract chapter markers and timestamps from a YouTube video. Returns chapter titles with start and end times. Not all videos have chapters. Returns empty list if none found.',
|
|
60
|
+
inputSchema: getChaptersSchema,
|
|
61
|
+
outputSchema: getChaptersOutputSchema,
|
|
62
|
+
annotations: {
|
|
63
|
+
readOnlyHint: true,
|
|
64
|
+
destructiveHint: false,
|
|
65
|
+
idempotentHint: true,
|
|
66
|
+
openWorldHint: true,
|
|
67
|
+
},
|
|
68
|
+
handler: getChaptersHandler,
|
|
69
|
+
}),
|
|
70
|
+
defineTool({
|
|
71
|
+
name: 'get_comments',
|
|
72
|
+
mode: 'all',
|
|
73
|
+
title: 'Get YouTube Video Comments',
|
|
74
|
+
description: 'Get top comments from a YouTube video sorted by popularity. Returns author, text, like count, and pinned status. Only top-level comments, no replies.',
|
|
75
|
+
inputSchema: getCommentsSchema,
|
|
76
|
+
outputSchema: getCommentsOutputSchema,
|
|
77
|
+
annotations: {
|
|
78
|
+
readOnlyHint: true,
|
|
79
|
+
destructiveHint: false,
|
|
80
|
+
idempotentHint: true,
|
|
81
|
+
openWorldHint: true,
|
|
82
|
+
},
|
|
83
|
+
handler: getCommentsHandler,
|
|
84
|
+
}),
|
|
85
|
+
defineTool({
|
|
86
|
+
name: 'list_formats',
|
|
87
|
+
mode: 'all',
|
|
88
|
+
title: 'List YouTube Video Formats',
|
|
89
|
+
description: 'List all available download formats for a YouTube video. Returns format IDs, extensions, resolutions, FPS, codecs, and file sizes. Grouped by video+audio, video-only, and audio-only.',
|
|
90
|
+
inputSchema: listFormatsSchema,
|
|
91
|
+
outputSchema: listFormatsOutputSchema,
|
|
92
|
+
annotations: {
|
|
93
|
+
readOnlyHint: true,
|
|
94
|
+
destructiveHint: false,
|
|
95
|
+
idempotentHint: true,
|
|
96
|
+
openWorldHint: true,
|
|
97
|
+
},
|
|
98
|
+
handler: listFormatsHandler,
|
|
99
|
+
}),
|
|
100
|
+
];
|
|
101
|
+
//# sourceMappingURL=video-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video-tools.js","sourceRoot":"","sources":["../../src/registry/video-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/resources.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUzE;;;;;;GAMG;AAEH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAkJjF"}
|
package/dist/resources.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { getLibraryItem, listLibrary } from './utils/storage.js';
|
|
3
|
+
import { hasProfile, listManifests, readProfile, requireManifest } from './utils/brain-storage.js';
|
|
4
|
+
import { registerThumbnailResource } from './thumbnail-resource.js';
|
|
5
|
+
import { YouTubeError } from './utils/errors.js';
|
|
3
6
|
import { getTranscript } from './utils/youtube.js';
|
|
4
7
|
import { segmentsToTimestamped } from './utils/transcript.js';
|
|
8
|
+
import { guardedResource } from './utils/guard.js';
|
|
5
9
|
/**
|
|
6
10
|
* Saved notes and cached transcripts, exposed as MCP resources.
|
|
7
11
|
*
|
|
@@ -14,7 +18,7 @@ export function registerResources(server, mode) {
|
|
|
14
18
|
title: 'Video transcript',
|
|
15
19
|
description: 'Timestamped transcript for a YouTube video, fetched and cached on first read.',
|
|
16
20
|
mimeType: 'text/plain',
|
|
17
|
-
}, async (uri, { videoId }) => {
|
|
21
|
+
}, guardedResource(async (uri, { videoId }) => {
|
|
18
22
|
const id = Array.isArray(videoId) ? videoId[0] : videoId;
|
|
19
23
|
const transcript = await getTranscript(id ?? '');
|
|
20
24
|
return {
|
|
@@ -26,12 +30,12 @@ export function registerResources(server, mode) {
|
|
|
26
30
|
},
|
|
27
31
|
],
|
|
28
32
|
};
|
|
29
|
-
});
|
|
33
|
+
}));
|
|
30
34
|
if (mode !== 'stdio')
|
|
31
35
|
return;
|
|
32
36
|
server.registerResource('library-item', new ResourceTemplate('youtube://library/{videoId}/{contentType}', {
|
|
33
37
|
// Enumerate what is actually saved, so a client can browse the library.
|
|
34
|
-
list: async () => {
|
|
38
|
+
list: guardedResource(async () => {
|
|
35
39
|
const items = await listLibrary();
|
|
36
40
|
return {
|
|
37
41
|
resources: items.flatMap((item) => [
|
|
@@ -55,18 +59,83 @@ export function registerResources(server, mode) {
|
|
|
55
59
|
: []),
|
|
56
60
|
]),
|
|
57
61
|
};
|
|
58
|
-
},
|
|
62
|
+
}),
|
|
59
63
|
}), {
|
|
60
64
|
title: 'Saved library note',
|
|
61
65
|
description: 'A summary or skill note previously saved to the local knowledge library.',
|
|
62
66
|
mimeType: 'text/markdown',
|
|
63
|
-
}, async (uri, { videoId, contentType }) => {
|
|
67
|
+
}, guardedResource(async (uri, { videoId, contentType }) => {
|
|
64
68
|
const id = Array.isArray(videoId) ? videoId[0] : videoId;
|
|
65
69
|
const type = Array.isArray(contentType) ? contentType[0] : contentType;
|
|
66
70
|
const wanted = type === 'skill' ? 'skill' : 'summary';
|
|
67
71
|
const item = await getLibraryItem(id ?? '', wanted);
|
|
68
72
|
const text = (wanted === 'skill' ? item.skill : item.summary) ?? '';
|
|
69
73
|
return { contents: [{ uri: uri.href, mimeType: 'text/markdown', text }] };
|
|
70
|
-
});
|
|
74
|
+
}));
|
|
75
|
+
server.registerResource('brain', new ResourceTemplate('youtube://brain/{channelId}/{part}', {
|
|
76
|
+
// Only what a client can usefully attach: the manifest describes the
|
|
77
|
+
// whole brain, and the profile is the written account of it. The passages
|
|
78
|
+
// are not offered as a resource — they are tens of megabytes and exist to
|
|
79
|
+
// be searched, not read.
|
|
80
|
+
list: guardedResource(async () => {
|
|
81
|
+
const brains = await listManifests();
|
|
82
|
+
return {
|
|
83
|
+
resources: brains.flatMap((brain) => [
|
|
84
|
+
{
|
|
85
|
+
uri: `youtube://brain/${brain.channel.channelId}/manifest`,
|
|
86
|
+
name: `${brain.channel.name} (brain)`,
|
|
87
|
+
mimeType: 'application/json',
|
|
88
|
+
},
|
|
89
|
+
...(hasProfile(brain.channel.channelId)
|
|
90
|
+
? [
|
|
91
|
+
{
|
|
92
|
+
uri: `youtube://brain/${brain.channel.channelId}/profile`,
|
|
93
|
+
name: `${brain.channel.name} (profile)`,
|
|
94
|
+
mimeType: 'text/markdown',
|
|
95
|
+
},
|
|
96
|
+
]
|
|
97
|
+
: []),
|
|
98
|
+
]),
|
|
99
|
+
};
|
|
100
|
+
}),
|
|
101
|
+
}), {
|
|
102
|
+
title: 'Channel brain',
|
|
103
|
+
description: "A channel brain's manifest — what it covers and what it measured — or the written profile saved beside it.",
|
|
104
|
+
mimeType: 'application/json',
|
|
105
|
+
}, guardedResource(async (uri, { channelId, part }) => {
|
|
106
|
+
const id = first(channelId);
|
|
107
|
+
const wanted = first(part);
|
|
108
|
+
// Returning the manifest for an unrecognised part would answer a question
|
|
109
|
+
// nobody asked, and look like the URI was understood.
|
|
110
|
+
if (wanted !== 'manifest' && wanted !== 'profile') {
|
|
111
|
+
throw new YouTubeError('INVALID_INPUT', `"${wanted}" is not part of a brain.`, {
|
|
112
|
+
nextStep: `Read youtube://brain/${id}/manifest or youtube://brain/${id}/profile.`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
if (wanted === 'profile') {
|
|
116
|
+
const profile = await readProfile(id);
|
|
117
|
+
if (profile === undefined) {
|
|
118
|
+
throw new YouTubeError('NOT_FOUND', `No profile has been saved for ${id}.`, {
|
|
119
|
+
nextStep: 'Call save_brain_profile to write one, after reading the brain with ask_brain.',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return { contents: [{ uri: uri.href, mimeType: 'text/markdown', text: profile }] };
|
|
123
|
+
}
|
|
124
|
+
const manifest = await requireManifest(id);
|
|
125
|
+
return {
|
|
126
|
+
contents: [
|
|
127
|
+
{
|
|
128
|
+
uri: uri.href,
|
|
129
|
+
mimeType: 'application/json',
|
|
130
|
+
text: JSON.stringify(manifest, null, 2),
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
};
|
|
134
|
+
}));
|
|
135
|
+
registerThumbnailResource(server);
|
|
136
|
+
}
|
|
137
|
+
/** Template variables arrive as a string or, for a repeated segment, an array. */
|
|
138
|
+
function first(value) {
|
|
139
|
+
return (Array.isArray(value) ? value[0] : value) ?? '';
|
|
71
140
|
}
|
|
72
141
|
//# sourceMappingURL=resources.js.map
|
package/dist/resources.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|