youtube-knowledge-mcp 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -41
- package/dist/brain-schemas.d.ts +10 -0
- package/dist/brain-schemas.d.ts.map +1 -1
- package/dist/harvest-schemas.d.ts +6 -6
- package/dist/harvest-schemas.d.ts.map +1 -1
- package/dist/harvest-schemas.js +5 -0
- package/dist/harvest-schemas.js.map +1 -1
- package/dist/registry/brain-tools.d.ts.map +1 -1
- package/dist/registry/brain-tools.js +16 -0
- package/dist/registry/brain-tools.js.map +1 -1
- package/dist/registry/channel-tools.d.ts.map +1 -1
- package/dist/registry/channel-tools.js +16 -0
- package/dist/registry/channel-tools.js.map +1 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +4 -0
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/media-tools.d.ts.map +1 -1
- package/dist/registry/media-tools.js +31 -0
- package/dist/registry/media-tools.js.map +1 -1
- package/dist/registry/store-tools.d.ts +9 -0
- package/dist/registry/store-tools.d.ts.map +1 -0
- package/dist/registry/store-tools.js +59 -0
- package/dist/registry/store-tools.js.map +1 -0
- package/dist/registry/transcript-tools.d.ts +4 -1
- package/dist/registry/transcript-tools.d.ts.map +1 -1
- package/dist/registry/transcript-tools.js +20 -1
- package/dist/registry/transcript-tools.js.map +1 -1
- package/dist/registry/video-tools.d.ts.map +1 -1
- package/dist/registry/video-tools.js +48 -0
- package/dist/registry/video-tools.js.map +1 -1
- package/dist/registry/vision-tools.d.ts +7 -0
- package/dist/registry/vision-tools.d.ts.map +1 -0
- package/dist/registry/vision-tools.js +55 -0
- package/dist/registry/vision-tools.js.map +1 -0
- package/dist/schemas.d.ts +6 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +2 -0
- package/dist/schemas.js.map +1 -1
- package/dist/thumbnail-schemas.d.ts +10 -0
- package/dist/thumbnail-schemas.d.ts.map +1 -1
- package/dist/tools/ask-brains.d.ts +66 -0
- package/dist/tools/ask-brains.d.ts.map +1 -0
- package/dist/tools/ask-brains.js +111 -0
- package/dist/tools/ask-brains.js.map +1 -0
- package/dist/tools/check-health.d.ts +16 -6
- package/dist/tools/check-health.d.ts.map +1 -1
- package/dist/tools/check-health.js +30 -1
- package/dist/tools/check-health.js.map +1 -1
- package/dist/tools/check-new-uploads.d.ts +55 -0
- package/dist/tools/check-new-uploads.d.ts.map +1 -0
- package/dist/tools/check-new-uploads.js +74 -0
- package/dist/tools/check-new-uploads.js.map +1 -0
- package/dist/tools/clips.d.ts +15 -0
- package/dist/tools/clips.d.ts.map +1 -1
- package/dist/tools/clips.js +5 -5
- package/dist/tools/clips.js.map +1 -1
- package/dist/tools/detect-scenes.d.ts +38 -0
- package/dist/tools/detect-scenes.d.ts.map +1 -0
- package/dist/tools/detect-scenes.js +66 -0
- package/dist/tools/detect-scenes.js.map +1 -0
- package/dist/tools/export-data.d.ts +85 -0
- package/dist/tools/export-data.d.ts.map +1 -0
- package/dist/tools/export-data.js +99 -0
- package/dist/tools/export-data.js.map +1 -0
- package/dist/tools/frames-subtitles.d.ts.map +1 -1
- package/dist/tools/frames-subtitles.js +16 -8
- package/dist/tools/frames-subtitles.js.map +1 -1
- package/dist/tools/frames.d.ts +73 -0
- package/dist/tools/frames.d.ts.map +1 -0
- package/dist/tools/frames.js +136 -0
- package/dist/tools/frames.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 +4 -0
- package/dist/tools/get-channel-info.js.map +1 -1
- package/dist/tools/get-comments.d.ts +5 -5
- package/dist/tools/get-coverage.d.ts +5 -5
- package/dist/tools/get-sponsor-segments.d.ts +49 -0
- package/dist/tools/get-sponsor-segments.d.ts.map +1 -0
- package/dist/tools/get-sponsor-segments.js +61 -0
- package/dist/tools/get-sponsor-segments.js.map +1 -0
- package/dist/tools/get-thumbnail.d.ts.map +1 -1
- package/dist/tools/get-thumbnail.js +2 -1
- package/dist/tools/get-thumbnail.js.map +1 -1
- package/dist/tools/get-transcript.d.ts +1 -0
- package/dist/tools/get-transcript.d.ts.map +1 -1
- package/dist/tools/get-transcript.js +11 -4
- package/dist/tools/get-transcript.js.map +1 -1
- package/dist/tools/get-video-details.d.ts +118 -0
- package/dist/tools/get-video-details.d.ts.map +1 -0
- package/dist/tools/get-video-details.js +147 -0
- package/dist/tools/get-video-details.js.map +1 -0
- package/dist/tools/gif-concat.d.ts +49 -0
- package/dist/tools/gif-concat.d.ts.map +1 -0
- package/dist/tools/gif-concat.js +96 -0
- package/dist/tools/gif-concat.js.map +1 -0
- package/dist/tools/harvest-channel.d.ts +5 -5
- package/dist/tools/harvest-comments.d.ts +5 -5
- package/dist/tools/harvest-details.d.ts +84 -0
- package/dist/tools/harvest-details.d.ts.map +1 -0
- package/dist/tools/harvest-details.js +71 -0
- package/dist/tools/harvest-details.js.map +1 -0
- package/dist/tools/list-captions.d.ts +17 -0
- package/dist/tools/list-captions.d.ts.map +1 -0
- package/dist/tools/list-captions.js +60 -0
- package/dist/tools/list-captions.js.map +1 -0
- package/dist/tools/list-channel-playlists.d.ts +30 -0
- package/dist/tools/list-channel-playlists.d.ts.map +1 -0
- package/dist/tools/list-channel-playlists.js +44 -0
- package/dist/tools/list-channel-playlists.js.map +1 -0
- package/dist/tools/query-comments.d.ts +5 -5
- package/dist/tools/query-videos.d.ts +5 -5
- package/dist/tools/search-channels.d.ts +6 -0
- package/dist/tools/search-channels.d.ts.map +1 -1
- package/dist/tools/transcribe-video.d.ts +28 -0
- package/dist/tools/transcribe-video.d.ts.map +1 -0
- package/dist/tools/transcribe-video.js +52 -0
- package/dist/tools/transcribe-video.js.map +1 -0
- package/dist/utils/brain-fusion.d.ts +24 -0
- package/dist/utils/brain-fusion.d.ts.map +1 -0
- package/dist/utils/brain-fusion.js +18 -0
- package/dist/utils/brain-fusion.js.map +1 -0
- package/dist/utils/channel-playlists.d.ts +21 -0
- package/dist/utils/channel-playlists.d.ts.map +1 -0
- package/dist/utils/channel-playlists.js +56 -0
- package/dist/utils/channel-playlists.js.map +1 -0
- package/dist/utils/clips.d.ts.map +1 -1
- package/dist/utils/clips.js +3 -17
- package/dist/utils/clips.js.map +1 -1
- package/dist/utils/concat.d.ts +19 -0
- package/dist/utils/concat.d.ts.map +1 -0
- package/dist/utils/concat.js +135 -0
- package/dist/utils/concat.js.map +1 -0
- package/dist/utils/contact-sheet.d.ts +28 -0
- package/dist/utils/contact-sheet.d.ts.map +1 -0
- package/dist/utils/contact-sheet.js +65 -0
- package/dist/utils/contact-sheet.js.map +1 -0
- package/dist/utils/detail-batch.d.ts +25 -0
- package/dist/utils/detail-batch.d.ts.map +1 -0
- package/dist/utils/detail-batch.js +58 -0
- package/dist/utils/detail-batch.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 +10 -0
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/export-data.d.ts +41 -0
- package/dist/utils/export-data.d.ts.map +1 -0
- package/dist/utils/export-data.js +114 -0
- package/dist/utils/export-data.js.map +1 -0
- package/dist/utils/export-format.d.ts +23 -0
- package/dist/utils/export-format.d.ts.map +1 -0
- package/dist/utils/export-format.js +59 -0
- package/dist/utils/export-format.js.map +1 -0
- package/dist/utils/export-load.d.ts +28 -0
- package/dist/utils/export-load.d.ts.map +1 -0
- package/dist/utils/export-load.js +70 -0
- package/dist/utils/export-load.js.map +1 -0
- package/dist/utils/export-rows.d.ts +35 -0
- package/dist/utils/export-rows.d.ts.map +1 -0
- package/dist/utils/export-rows.js +69 -0
- package/dist/utils/export-rows.js.map +1 -0
- package/dist/utils/ffmpeg.d.ts +26 -0
- package/dist/utils/ffmpeg.d.ts.map +1 -0
- package/dist/utils/ffmpeg.js +28 -0
- package/dist/utils/ffmpeg.js.map +1 -0
- package/dist/utils/format.d.ts +6 -0
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +4 -0
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/frame-plan.d.ts +24 -0
- package/dist/utils/frame-plan.d.ts.map +1 -0
- package/dist/utils/frame-plan.js +58 -0
- package/dist/utils/frame-plan.js.map +1 -0
- package/dist/utils/frames.d.ts +32 -0
- package/dist/utils/frames.d.ts.map +1 -0
- package/dist/utils/frames.js +60 -0
- package/dist/utils/frames.js.map +1 -0
- package/dist/utils/gif.d.ts +31 -0
- package/dist/utils/gif.d.ts.map +1 -0
- package/dist/utils/gif.js +77 -0
- package/dist/utils/gif.js.map +1 -0
- package/dist/utils/harvest-catalog.d.ts +10 -0
- package/dist/utils/harvest-catalog.d.ts.map +1 -1
- package/dist/utils/harvest-catalog.js +14 -5
- package/dist/utils/harvest-catalog.js.map +1 -1
- package/dist/utils/harvest-details.d.ts +30 -0
- package/dist/utils/harvest-details.d.ts.map +1 -0
- package/dist/utils/harvest-details.js +98 -0
- package/dist/utils/harvest-details.js.map +1 -0
- package/dist/utils/local-transcription.d.ts +14 -0
- package/dist/utils/local-transcription.d.ts.map +1 -0
- package/dist/utils/local-transcription.js +85 -0
- package/dist/utils/local-transcription.js.map +1 -0
- package/dist/utils/moment.d.ts +24 -0
- package/dist/utils/moment.d.ts.map +1 -0
- package/dist/utils/moment.js +22 -0
- package/dist/utils/moment.js.map +1 -0
- package/dist/utils/most-replayed.d.ts +15 -0
- package/dist/utils/most-replayed.d.ts.map +1 -0
- package/dist/utils/most-replayed.js +25 -0
- package/dist/utils/most-replayed.js.map +1 -0
- package/dist/utils/scenes.d.ts +39 -0
- package/dist/utils/scenes.d.ts.map +1 -0
- package/dist/utils/scenes.js +83 -0
- package/dist/utils/scenes.js.map +1 -0
- package/dist/utils/seconds.d.ts +5 -0
- package/dist/utils/seconds.d.ts.map +1 -0
- package/dist/utils/seconds.js +7 -0
- package/dist/utils/seconds.js.map +1 -0
- package/dist/utils/sponsorblock.d.ts +24 -0
- package/dist/utils/sponsorblock.d.ts.map +1 -0
- package/dist/utils/sponsorblock.js +153 -0
- package/dist/utils/sponsorblock.js.map +1 -0
- package/dist/utils/transcript-cache.d.ts +5 -1
- package/dist/utils/transcript-cache.d.ts.map +1 -1
- package/dist/utils/transcript-cache.js +31 -50
- package/dist/utils/transcript-cache.js.map +1 -1
- package/dist/utils/transcript-files.d.ts +24 -0
- package/dist/utils/transcript-files.d.ts.map +1 -0
- package/dist/utils/transcript-files.js +61 -0
- package/dist/utils/transcript-files.js.map +1 -0
- package/dist/utils/transcript.d.ts +3 -0
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +2 -0
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/upload-check.d.ts +38 -0
- package/dist/utils/upload-check.d.ts.map +1 -0
- package/dist/utils/upload-check.js +93 -0
- package/dist/utils/upload-check.js.map +1 -0
- package/dist/utils/validate.d.ts +2 -0
- package/dist/utils/validate.d.ts.map +1 -1
- package/dist/utils/validate.js +4 -0
- package/dist/utils/validate.js.map +1 -1
- package/dist/utils/video-detail-store.d.ts +47 -0
- package/dist/utils/video-detail-store.d.ts.map +1 -0
- package/dist/utils/video-detail-store.js +89 -0
- package/dist/utils/video-detail-store.js.map +1 -0
- package/dist/utils/video-stats-cache.js +1 -1
- package/dist/utils/video-stats-schema.d.ts +187 -0
- package/dist/utils/video-stats-schema.d.ts.map +1 -0
- package/dist/utils/video-stats-schema.js +50 -0
- package/dist/utils/video-stats-schema.js.map +1 -0
- package/dist/utils/video-stats-storage.d.ts +16 -0
- package/dist/utils/video-stats-storage.d.ts.map +1 -0
- package/dist/utils/video-stats-storage.js +37 -0
- package/dist/utils/video-stats-storage.js.map +1 -0
- package/dist/utils/video-stats.d.ts +23 -127
- package/dist/utils/video-stats.d.ts.map +1 -1
- package/dist/utils/video-stats.js +42 -102
- package/dist/utils/video-stats.js.map +1 -1
- package/dist/utils/video-stream.d.ts +21 -0
- package/dist/utils/video-stream.d.ts.map +1 -0
- package/dist/utils/video-stream.js +36 -0
- package/dist/utils/video-stream.js.map +1 -0
- package/dist/utils/whisper.d.ts +39 -0
- package/dist/utils/whisper.d.ts.map +1 -0
- package/dist/utils/whisper.js +137 -0
- package/dist/utils/whisper.js.map +1 -0
- package/dist/utils/youtube-channel.d.ts +4 -0
- package/dist/utils/youtube-channel.d.ts.map +1 -1
- package/dist/utils/youtube-channel.js +6 -0
- package/dist/utils/youtube-channel.js.map +1 -1
- package/dist/utils/youtube-schemas.d.ts +6 -0
- package/dist/utils/youtube-schemas.d.ts.map +1 -1
- package/dist/utils/youtube-schemas.js +2 -0
- package/dist/utils/youtube-schemas.js.map +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { fileResult, formatFilesize } from '../utils/format.js';
|
|
3
|
+
import { DEFAULT_GIF_FPS, DEFAULT_GIF_WIDTH, extractGif } from '../utils/gif.js';
|
|
4
|
+
import { MAX_CONCAT_FILES, MIN_CONCAT_FILES, concatClips } from '../utils/concat.js';
|
|
5
|
+
import { formatTimestamp } from '../utils/transcript.js';
|
|
6
|
+
import { RANGE_FIELDS, parseRange } from './clips.js';
|
|
7
|
+
/** Small pieces of video editing: an animated GIF from a moment, and clips joined into one. */
|
|
8
|
+
// -- extract_gif ---------------------------------------------------------
|
|
9
|
+
export const extractGifSchema = {
|
|
10
|
+
video: z.string().describe('YouTube video ID or full URL'),
|
|
11
|
+
...RANGE_FIELDS,
|
|
12
|
+
width: z
|
|
13
|
+
.number()
|
|
14
|
+
.int()
|
|
15
|
+
.min(120)
|
|
16
|
+
.max(800)
|
|
17
|
+
.default(DEFAULT_GIF_WIDTH)
|
|
18
|
+
.describe(`GIF width in pixels. Default: ${String(DEFAULT_GIF_WIDTH)}`),
|
|
19
|
+
fps: z
|
|
20
|
+
.number()
|
|
21
|
+
.int()
|
|
22
|
+
.min(4)
|
|
23
|
+
.max(24)
|
|
24
|
+
.default(DEFAULT_GIF_FPS)
|
|
25
|
+
.describe(`Frames per second. Default: ${String(DEFAULT_GIF_FPS)}`),
|
|
26
|
+
};
|
|
27
|
+
export const extractGifOutputSchema = {
|
|
28
|
+
videoId: z.string(),
|
|
29
|
+
title: z.string(),
|
|
30
|
+
filePath: z.string(),
|
|
31
|
+
startSeconds: z.number(),
|
|
32
|
+
endSeconds: z.number(),
|
|
33
|
+
durationSeconds: z.number(),
|
|
34
|
+
width: z.number().int(),
|
|
35
|
+
fps: z.number().int(),
|
|
36
|
+
bytes: z.number().int(),
|
|
37
|
+
};
|
|
38
|
+
export async function extractGifHandler(args) {
|
|
39
|
+
const result = await extractGif(args.video, parseRange(args), {
|
|
40
|
+
width: args.width,
|
|
41
|
+
fps: args.fps,
|
|
42
|
+
outputDir: args.outputDir,
|
|
43
|
+
});
|
|
44
|
+
return fileResult([
|
|
45
|
+
'✓ GIF made',
|
|
46
|
+
'',
|
|
47
|
+
result.title,
|
|
48
|
+
`${formatTimestamp(result.start)} – ${formatTimestamp(result.end)}, ${String(result.width)}px at ${String(result.fps)} fps, ${formatFilesize(result.bytes)}`,
|
|
49
|
+
'',
|
|
50
|
+
result.filePath,
|
|
51
|
+
].join('\n'), {
|
|
52
|
+
videoId: result.videoId,
|
|
53
|
+
title: result.title,
|
|
54
|
+
filePath: result.filePath,
|
|
55
|
+
startSeconds: result.start,
|
|
56
|
+
endSeconds: result.end,
|
|
57
|
+
durationSeconds: result.duration,
|
|
58
|
+
width: result.width,
|
|
59
|
+
fps: result.fps,
|
|
60
|
+
bytes: result.bytes,
|
|
61
|
+
}, { path: result.filePath, name: `${result.title} GIF`, mimeType: 'image/gif' });
|
|
62
|
+
}
|
|
63
|
+
// -- concat_clips --------------------------------------------------------
|
|
64
|
+
export const concatClipsSchema = {
|
|
65
|
+
clips: z
|
|
66
|
+
.array(z.string().max(1024))
|
|
67
|
+
.min(MIN_CONCAT_FILES)
|
|
68
|
+
.max(MAX_CONCAT_FILES)
|
|
69
|
+
.describe(`Paths of the video files to join, in order, each inside your home directory. Between ${String(MIN_CONCAT_FILES)} and ${String(MAX_CONCAT_FILES)}. Typically the paths extract_clip returned.`),
|
|
70
|
+
name: z
|
|
71
|
+
.string()
|
|
72
|
+
.max(80)
|
|
73
|
+
.optional()
|
|
74
|
+
.describe('Name for the joined file, without extension. Default: montage-<hash of the inputs>'),
|
|
75
|
+
outputDir: z
|
|
76
|
+
.string()
|
|
77
|
+
.optional()
|
|
78
|
+
.describe('Where to write the file. Must be inside your home directory.'),
|
|
79
|
+
};
|
|
80
|
+
export const concatClipsOutputSchema = {
|
|
81
|
+
filePath: z.string(),
|
|
82
|
+
clips: z.number().int(),
|
|
83
|
+
bytes: z.number().int(),
|
|
84
|
+
};
|
|
85
|
+
export async function concatClipsHandler(args) {
|
|
86
|
+
const { clips, name, outputDir } = args;
|
|
87
|
+
const result = await concatClips(clips, { name, outputDir });
|
|
88
|
+
return fileResult([
|
|
89
|
+
`✓ ${String(result.clips)} clips joined`,
|
|
90
|
+
'',
|
|
91
|
+
formatFilesize(result.bytes),
|
|
92
|
+
'',
|
|
93
|
+
result.filePath,
|
|
94
|
+
].join('\n'), { filePath: result.filePath, clips: result.clips, bytes: result.bytes }, { path: result.filePath, name: 'Joined clips', mimeType: 'video/mp4' });
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=gif-concat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gif-concat.js","sourceRoot":"","sources":["../../src/tools/gif-concat.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@ export declare const harvestChannelOutputSchema: {
|
|
|
36
36
|
reason: z.ZodEnum<["COMPLETE", "CAP_REACHED", "BUDGET_SPENT", "RATE_LIMITED", "CANCELLED", "TIMEOUT", "SOURCE_REFUSED", "COMMENTS_DISABLED", "SOURCE_SILENT", "PARTIAL_ERROR", "NOT_ATTEMPTED"]>;
|
|
37
37
|
have: z.ZodNumber;
|
|
38
38
|
expected: z.ZodOptional<z.ZodNumber>;
|
|
39
|
-
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted"]>>;
|
|
39
|
+
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted", "store:catalog"]>>;
|
|
40
40
|
ranToExhaustion: z.ZodOptional<z.ZodBoolean>;
|
|
41
41
|
source: z.ZodString;
|
|
42
42
|
harvestedAt: z.ZodString;
|
|
@@ -46,33 +46,33 @@ export declare const harvestChannelOutputSchema: {
|
|
|
46
46
|
resumeToken: z.ZodOptional<z.ZodString>;
|
|
47
47
|
note: z.ZodOptional<z.ZodString>;
|
|
48
48
|
}, "strip", z.ZodTypeAny, {
|
|
49
|
+
source: string;
|
|
49
50
|
have: number;
|
|
50
51
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
51
52
|
targetId: string;
|
|
52
53
|
complete: boolean;
|
|
53
54
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
54
|
-
source: string;
|
|
55
55
|
harvestedAt: string;
|
|
56
56
|
expected?: number | undefined;
|
|
57
57
|
note?: string | undefined;
|
|
58
58
|
ranToExhaustion?: boolean | undefined;
|
|
59
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
59
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
60
60
|
staleAfter?: string | undefined;
|
|
61
61
|
limitApplied?: number | undefined;
|
|
62
62
|
sortApplied?: "top" | "new" | undefined;
|
|
63
63
|
resumeToken?: string | undefined;
|
|
64
64
|
}, {
|
|
65
|
+
source: string;
|
|
65
66
|
have: number;
|
|
66
67
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
67
68
|
targetId: string;
|
|
68
69
|
complete: boolean;
|
|
69
70
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
70
|
-
source: string;
|
|
71
71
|
harvestedAt: string;
|
|
72
72
|
expected?: number | undefined;
|
|
73
73
|
note?: string | undefined;
|
|
74
74
|
ranToExhaustion?: boolean | undefined;
|
|
75
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
75
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
76
76
|
staleAfter?: string | undefined;
|
|
77
77
|
limitApplied?: number | undefined;
|
|
78
78
|
sortApplied?: "top" | "new" | undefined;
|
|
@@ -21,7 +21,7 @@ export declare const harvestCommentsOutputSchema: {
|
|
|
21
21
|
reason: z.ZodEnum<["COMPLETE", "CAP_REACHED", "BUDGET_SPENT", "RATE_LIMITED", "CANCELLED", "TIMEOUT", "SOURCE_REFUSED", "COMMENTS_DISABLED", "SOURCE_SILENT", "PARTIAL_ERROR", "NOT_ATTEMPTED"]>;
|
|
22
22
|
have: z.ZodNumber;
|
|
23
23
|
expected: z.ZodOptional<z.ZodNumber>;
|
|
24
|
-
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted"]>>;
|
|
24
|
+
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted", "store:catalog"]>>;
|
|
25
25
|
ranToExhaustion: z.ZodOptional<z.ZodBoolean>;
|
|
26
26
|
source: z.ZodString;
|
|
27
27
|
harvestedAt: z.ZodString;
|
|
@@ -31,33 +31,33 @@ export declare const harvestCommentsOutputSchema: {
|
|
|
31
31
|
resumeToken: z.ZodOptional<z.ZodString>;
|
|
32
32
|
note: z.ZodOptional<z.ZodString>;
|
|
33
33
|
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
source: string;
|
|
34
35
|
have: number;
|
|
35
36
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
36
37
|
targetId: string;
|
|
37
38
|
complete: boolean;
|
|
38
39
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
39
|
-
source: string;
|
|
40
40
|
harvestedAt: string;
|
|
41
41
|
expected?: number | undefined;
|
|
42
42
|
note?: string | undefined;
|
|
43
43
|
ranToExhaustion?: boolean | undefined;
|
|
44
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
44
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
45
45
|
staleAfter?: string | undefined;
|
|
46
46
|
limitApplied?: number | undefined;
|
|
47
47
|
sortApplied?: "top" | "new" | undefined;
|
|
48
48
|
resumeToken?: string | undefined;
|
|
49
49
|
}, {
|
|
50
|
+
source: string;
|
|
50
51
|
have: number;
|
|
51
52
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
52
53
|
targetId: string;
|
|
53
54
|
complete: boolean;
|
|
54
55
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
55
|
-
source: string;
|
|
56
56
|
harvestedAt: string;
|
|
57
57
|
expected?: number | undefined;
|
|
58
58
|
note?: string | undefined;
|
|
59
59
|
ranToExhaustion?: boolean | undefined;
|
|
60
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
60
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
61
61
|
staleAfter?: string | undefined;
|
|
62
62
|
limitApplied?: number | undefined;
|
|
63
63
|
sortApplied?: "top" | "new" | undefined;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
export declare const harvestDetailsSchema: {
|
|
4
|
+
channel: z.ZodString;
|
|
5
|
+
maxVideos: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
retryUnreadable: z.ZodDefault<z.ZodBoolean>;
|
|
7
|
+
};
|
|
8
|
+
export declare const harvestDetailsOutputSchema: {
|
|
9
|
+
channelId: z.ZodString;
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
attempted: z.ZodNumber;
|
|
12
|
+
stored: z.ZodNumber;
|
|
13
|
+
failures: z.ZodArray<z.ZodObject<{
|
|
14
|
+
videoId: z.ZodString;
|
|
15
|
+
code: z.ZodString;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
code: string;
|
|
18
|
+
videoId: string;
|
|
19
|
+
}, {
|
|
20
|
+
code: string;
|
|
21
|
+
videoId: string;
|
|
22
|
+
}>, "many">;
|
|
23
|
+
remaining: z.ZodNumber;
|
|
24
|
+
stoppedBecause: z.ZodOptional<z.ZodString>;
|
|
25
|
+
coverage: z.ZodObject<{
|
|
26
|
+
scope: z.ZodEnum<["channel-catalog", "video-details", "video-comments"]>;
|
|
27
|
+
targetId: z.ZodString;
|
|
28
|
+
complete: z.ZodBoolean;
|
|
29
|
+
reason: z.ZodEnum<["COMPLETE", "CAP_REACHED", "BUDGET_SPENT", "RATE_LIMITED", "CANCELLED", "TIMEOUT", "SOURCE_REFUSED", "COMMENTS_DISABLED", "SOURCE_SILENT", "PARTIAL_ERROR", "NOT_ATTEMPTED"]>;
|
|
30
|
+
have: z.ZodNumber;
|
|
31
|
+
expected: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted", "store:catalog"]>>;
|
|
33
|
+
ranToExhaustion: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
source: z.ZodString;
|
|
35
|
+
harvestedAt: z.ZodString;
|
|
36
|
+
staleAfter: z.ZodOptional<z.ZodString>;
|
|
37
|
+
limitApplied: z.ZodOptional<z.ZodNumber>;
|
|
38
|
+
sortApplied: z.ZodOptional<z.ZodEnum<["top", "new"]>>;
|
|
39
|
+
resumeToken: z.ZodOptional<z.ZodString>;
|
|
40
|
+
note: z.ZodOptional<z.ZodString>;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
source: string;
|
|
43
|
+
have: number;
|
|
44
|
+
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
45
|
+
targetId: string;
|
|
46
|
+
complete: boolean;
|
|
47
|
+
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
48
|
+
harvestedAt: string;
|
|
49
|
+
expected?: number | undefined;
|
|
50
|
+
note?: string | undefined;
|
|
51
|
+
ranToExhaustion?: boolean | undefined;
|
|
52
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
53
|
+
staleAfter?: string | undefined;
|
|
54
|
+
limitApplied?: number | undefined;
|
|
55
|
+
sortApplied?: "top" | "new" | undefined;
|
|
56
|
+
resumeToken?: string | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
source: string;
|
|
59
|
+
have: number;
|
|
60
|
+
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
61
|
+
targetId: string;
|
|
62
|
+
complete: boolean;
|
|
63
|
+
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
64
|
+
harvestedAt: string;
|
|
65
|
+
expected?: number | undefined;
|
|
66
|
+
note?: string | undefined;
|
|
67
|
+
ranToExhaustion?: boolean | undefined;
|
|
68
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
69
|
+
staleAfter?: string | undefined;
|
|
70
|
+
limitApplied?: number | undefined;
|
|
71
|
+
sortApplied?: "top" | "new" | undefined;
|
|
72
|
+
resumeToken?: string | undefined;
|
|
73
|
+
}>;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Reads the full record of each catalogued video and keeps it in the store, a batch at a
|
|
77
|
+
* time. Calling it again continues with the next unread videos.
|
|
78
|
+
*/
|
|
79
|
+
export declare function harvestDetailsHandler(args: {
|
|
80
|
+
channel: string;
|
|
81
|
+
maxVideos: number;
|
|
82
|
+
retryUnreadable: boolean;
|
|
83
|
+
}): Promise<CallToolResult>;
|
|
84
|
+
//# sourceMappingURL=harvest-details.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harvest-details.d.ts","sourceRoot":"","sources":["../../src/tools/harvest-details.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAWzE,eAAO,MAAM,oBAAoB;;;;CAiBhC,CAAC;AAEF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYtC,CAAC;AAEF;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,cAAc,CAAC,CAkC1B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { coverageSchema } from '../harvest-schemas.js';
|
|
3
|
+
import { renderCoverage } from '../utils/coverage-text.js';
|
|
4
|
+
import { toolResult } from '../utils/format.js';
|
|
5
|
+
import { DEFAULT_DETAIL_BATCH, MAX_DETAIL_BATCH, harvestDetails, } from '../utils/harvest-details.js';
|
|
6
|
+
import { getStore } from '../utils/store.js';
|
|
7
|
+
export const harvestDetailsSchema = {
|
|
8
|
+
channel: z.string().max(256).describe('Channel URL, @handle, or channel id, already catalogued'),
|
|
9
|
+
maxVideos: z
|
|
10
|
+
.number()
|
|
11
|
+
.int()
|
|
12
|
+
.min(1)
|
|
13
|
+
.max(MAX_DETAIL_BATCH)
|
|
14
|
+
.default(DEFAULT_DETAIL_BATCH)
|
|
15
|
+
.describe(`How many unread videos to read in this call (max ${String(MAX_DETAIL_BATCH)}). Each is a full read, the request YouTube throttles hardest, so run it in batches. Default: ${String(DEFAULT_DETAIL_BATCH)}`),
|
|
16
|
+
retryUnreadable: z
|
|
17
|
+
.boolean()
|
|
18
|
+
.default(false)
|
|
19
|
+
.describe('Try again the videos earlier runs found private, members-only, age-gated or removed. Worth it after adding cookies. Default: false'),
|
|
20
|
+
};
|
|
21
|
+
export const harvestDetailsOutputSchema = {
|
|
22
|
+
channelId: z.string(),
|
|
23
|
+
name: z.string(),
|
|
24
|
+
attempted: z.number().int().describe('Videos read, or tried, in this call'),
|
|
25
|
+
stored: z.number().int().describe('Videos whose full record was kept'),
|
|
26
|
+
failures: z.array(z.object({ videoId: z.string(), code: z.string() })),
|
|
27
|
+
remaining: z.number().int().describe('Videos still unread that can be read'),
|
|
28
|
+
stoppedBecause: z
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('The refusal that ended the call early, when one did'),
|
|
32
|
+
coverage: coverageSchema,
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Reads the full record of each catalogued video and keeps it in the store, a batch at a
|
|
36
|
+
* time. Calling it again continues with the next unread videos.
|
|
37
|
+
*/
|
|
38
|
+
export async function harvestDetailsHandler(args) {
|
|
39
|
+
const store = await getStore();
|
|
40
|
+
const result = await harvestDetails(store, args.channel, {
|
|
41
|
+
maxVideos: args.maxVideos,
|
|
42
|
+
retryUnreadable: args.retryUnreadable,
|
|
43
|
+
});
|
|
44
|
+
const lines = [
|
|
45
|
+
renderCoverage(result.coverage),
|
|
46
|
+
'',
|
|
47
|
+
`${result.name}: ${String(result.stored)} of ${String(result.attempted)} videos read this run, ${String(result.remaining)} still unread.`,
|
|
48
|
+
...(result.stoppedBecause === undefined
|
|
49
|
+
? []
|
|
50
|
+
: [`Stopped early: ${result.stoppedBecause}. Everything read before it is kept.`]),
|
|
51
|
+
...(result.failures.length === 0
|
|
52
|
+
? []
|
|
53
|
+
: [
|
|
54
|
+
`Could not read: ${result.failures.map((failure) => `${failure.videoId} (${failure.code})`).join(', ')}`,
|
|
55
|
+
]),
|
|
56
|
+
...(result.remaining > 0 || result.stoppedBecause !== undefined
|
|
57
|
+
? ['', 'Call harvest_details again to continue with the next unread videos.']
|
|
58
|
+
: []),
|
|
59
|
+
];
|
|
60
|
+
return toolResult(lines.join('\n'), {
|
|
61
|
+
channelId: result.channelId,
|
|
62
|
+
name: result.name,
|
|
63
|
+
attempted: result.attempted,
|
|
64
|
+
stored: result.stored,
|
|
65
|
+
failures: result.failures,
|
|
66
|
+
remaining: result.remaining,
|
|
67
|
+
...(result.stoppedBecause === undefined ? {} : { stoppedBecause: result.stoppedBecause }),
|
|
68
|
+
coverage: result.coverage,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=harvest-details.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harvest-details.js","sourceRoot":"","sources":["../../src/tools/harvest-details.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,yDAAyD,CAAC;IAChG,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,gBAAgB,CAAC;SACrB,OAAO,CAAC,oBAAoB,CAAC;SAC7B,QAAQ,CACP,oDAAoD,MAAM,CAAC,gBAAgB,CAAC,iGAAiG,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAC5M;IACH,eAAe,EAAE,CAAC;SACf,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CACP,oIAAoI,CACrI;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IAC3E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;IACtE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC5E,cAAc,EAAE,CAAC;SACd,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,qDAAqD,CAAC;IAClE,QAAQ,EAAE,cAAc;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAI3C;IACC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE;QACvD,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,eAAe,EAAE,IAAI,CAAC,eAAe;KACtC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG;QACZ,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC/B,EAAE;QACF,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,0BAA0B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB;QACzI,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS;YACrC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,kBAAkB,MAAM,CAAC,cAAc,sCAAsC,CAAC,CAAC;QACpF,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAC9B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,mBAAmB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aACzG,CAAC;QACN,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,MAAM,CAAC,cAAc,KAAK,SAAS;YAC7D,CAAC,CAAC,CAAC,EAAE,EAAE,qEAAqE,CAAC;YAC7E,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IAEF,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAClC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC;QACzF,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
export declare const listCaptionsSchema: {
|
|
4
|
+
video: z.ZodString;
|
|
5
|
+
};
|
|
6
|
+
export declare const listCaptionsOutputSchema: {
|
|
7
|
+
videoId: z.ZodString;
|
|
8
|
+
title: z.ZodString;
|
|
9
|
+
hasCaptions: z.ZodBoolean;
|
|
10
|
+
manual: z.ZodArray<z.ZodString, "many">;
|
|
11
|
+
automatic: z.ZodArray<z.ZodString, "many">;
|
|
12
|
+
spokenLanguage: z.ZodOptional<z.ZodString>;
|
|
13
|
+
};
|
|
14
|
+
export declare function listCaptionsHandler({ video }: {
|
|
15
|
+
video: string;
|
|
16
|
+
}): Promise<CallToolResult>;
|
|
17
|
+
//# sourceMappingURL=list-captions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-captions.d.ts","sourceRoot":"","sources":["../../src/tools/list-captions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAazE,eAAO,MAAM,kBAAkB;;CAE9B,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;;;;;CAUpC,CAAC;AAMF,wBAAsB,mBAAmB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAyC/F"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { toolResult } from '../utils/format.js';
|
|
3
|
+
import { readVideoStats } from '../utils/video-stats-cache.js';
|
|
4
|
+
/**
|
|
5
|
+
* Which caption languages a video has, read from the same saved copy as
|
|
6
|
+
* get_video_details, so asking costs no extra request when that one was already made.
|
|
7
|
+
*/
|
|
8
|
+
/** Automatic captions come in every language YouTube can translate to; the text stays readable. */
|
|
9
|
+
const LISTED_AUTOMATIC_LANGUAGES = 25;
|
|
10
|
+
const ORIGINAL_SUFFIX = '-orig';
|
|
11
|
+
export const listCaptionsSchema = {
|
|
12
|
+
video: z.string().describe('YouTube video ID (e.g., dQw4w9WgXcQ) or full URL'),
|
|
13
|
+
};
|
|
14
|
+
export const listCaptionsOutputSchema = {
|
|
15
|
+
videoId: z.string(),
|
|
16
|
+
title: z.string(),
|
|
17
|
+
hasCaptions: z.boolean(),
|
|
18
|
+
manual: z.array(z.string()).describe('Language codes of captions a person wrote or uploaded'),
|
|
19
|
+
automatic: z.array(z.string()).describe('Language codes YouTube generated or translated'),
|
|
20
|
+
spokenLanguage: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe('The language YouTube recognised in the audio, when it says'),
|
|
24
|
+
};
|
|
25
|
+
function sortedUnique(codes) {
|
|
26
|
+
return [...new Set(codes)].sort();
|
|
27
|
+
}
|
|
28
|
+
export async function listCaptionsHandler({ video }) {
|
|
29
|
+
const { stats } = await readVideoStats(video);
|
|
30
|
+
const manual = sortedUnique(stats.captions.manual);
|
|
31
|
+
const automatic = sortedUnique(stats.captions.automatic.filter((code) => !code.endsWith(ORIGINAL_SUFFIX)));
|
|
32
|
+
const original = stats.captions.automatic.find((code) => code.endsWith(ORIGINAL_SUFFIX));
|
|
33
|
+
const spokenLanguage = original?.slice(0, -ORIGINAL_SUFFIX.length);
|
|
34
|
+
const hasCaptions = manual.length > 0 || automatic.length > 0;
|
|
35
|
+
const structured = {
|
|
36
|
+
videoId: stats.id,
|
|
37
|
+
title: stats.title,
|
|
38
|
+
hasCaptions,
|
|
39
|
+
manual,
|
|
40
|
+
automatic,
|
|
41
|
+
...(spokenLanguage === undefined ? {} : { spokenLanguage }),
|
|
42
|
+
};
|
|
43
|
+
if (!hasCaptions) {
|
|
44
|
+
return toolResult([
|
|
45
|
+
`${stats.title}: this video has no captions in any language.`,
|
|
46
|
+
'Use get_comments for viewer discussion, or get_video_info for the description.',
|
|
47
|
+
].join('\n'), structured);
|
|
48
|
+
}
|
|
49
|
+
const hidden = automatic.length - LISTED_AUTOMATIC_LANGUAGES;
|
|
50
|
+
const lines = [
|
|
51
|
+
stats.title,
|
|
52
|
+
...(spokenLanguage === undefined ? [] : [`Spoken language: ${spokenLanguage}`]),
|
|
53
|
+
`Manual (${manual.length}): ${manual.join(', ') || 'none'}`,
|
|
54
|
+
`Automatic (${automatic.length}): ${automatic.slice(0, LISTED_AUTOMATIC_LANGUAGES).join(', ') || 'none'}${hidden > 0 ? `, and ${hidden} more` : ''}`,
|
|
55
|
+
'',
|
|
56
|
+
'Pass any of these codes as language to get_transcript.',
|
|
57
|
+
];
|
|
58
|
+
return toolResult(lines.join('\n'), structured);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=list-captions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-captions.js","sourceRoot":"","sources":["../../src/tools/list-captions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
export declare const listChannelPlaylistsSchema: {
|
|
4
|
+
channel: z.ZodString;
|
|
5
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
};
|
|
7
|
+
export declare const listChannelPlaylistsOutputSchema: {
|
|
8
|
+
channelId: z.ZodString;
|
|
9
|
+
channelName: z.ZodString;
|
|
10
|
+
count: z.ZodNumber;
|
|
11
|
+
mayHaveMore: z.ZodBoolean;
|
|
12
|
+
playlists: z.ZodArray<z.ZodObject<{
|
|
13
|
+
id: z.ZodString;
|
|
14
|
+
title: z.ZodString;
|
|
15
|
+
url: z.ZodString;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
id: string;
|
|
18
|
+
title: string;
|
|
19
|
+
url: string;
|
|
20
|
+
}, {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
url: string;
|
|
24
|
+
}>, "many">;
|
|
25
|
+
};
|
|
26
|
+
export declare function listChannelPlaylistsHandler(args: {
|
|
27
|
+
channel: string;
|
|
28
|
+
limit: number;
|
|
29
|
+
}): Promise<CallToolResult>;
|
|
30
|
+
//# sourceMappingURL=list-channel-playlists.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-channel-playlists.d.ts","sourceRoot":"","sources":["../../src/tools/list-channel-playlists.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAMzE,eAAO,MAAM,0BAA0B;;;CActC,CAAC;AAEF,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;CAM5C,CAAC;AAEF,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,cAAc,CAAC,CAyB1B"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { toolResult } from '../utils/format.js';
|
|
3
|
+
import { MAX_CHANNEL_PLAYLISTS, listChannelPlaylists } from '../utils/channel-playlists.js';
|
|
4
|
+
const DEFAULT_LIMIT = 50;
|
|
5
|
+
export const listChannelPlaylistsSchema = {
|
|
6
|
+
channel: z
|
|
7
|
+
.string()
|
|
8
|
+
.max(256)
|
|
9
|
+
.describe('YouTube channel URL, handle (e.g., @Fireship), channel id or channel name'),
|
|
10
|
+
limit: z
|
|
11
|
+
.number()
|
|
12
|
+
.int()
|
|
13
|
+
.min(1)
|
|
14
|
+
.max(MAX_CHANNEL_PLAYLISTS)
|
|
15
|
+
.default(DEFAULT_LIMIT)
|
|
16
|
+
.describe(`How many playlists to list, up to ${MAX_CHANNEL_PLAYLISTS}. Default: ${DEFAULT_LIMIT}`),
|
|
17
|
+
};
|
|
18
|
+
export const listChannelPlaylistsOutputSchema = {
|
|
19
|
+
channelId: z.string(),
|
|
20
|
+
channelName: z.string(),
|
|
21
|
+
count: z.number().int(),
|
|
22
|
+
mayHaveMore: z.boolean().describe('True when the limit was reached, so there may be more'),
|
|
23
|
+
playlists: z.array(z.object({ id: z.string(), title: z.string(), url: z.string() })),
|
|
24
|
+
};
|
|
25
|
+
export async function listChannelPlaylistsHandler(args) {
|
|
26
|
+
const { channelId, channelName, playlists, mayHaveMore } = await listChannelPlaylists(args.channel, args.limit);
|
|
27
|
+
const structured = { channelId, channelName, count: playlists.length, mayHaveMore, playlists };
|
|
28
|
+
if (playlists.length === 0) {
|
|
29
|
+
return toolResult(`${channelName} has no public playlists.`, structured);
|
|
30
|
+
}
|
|
31
|
+
const lines = [
|
|
32
|
+
`${channelName}: ${playlists.length} playlists`,
|
|
33
|
+
'',
|
|
34
|
+
...playlists.flatMap((playlist, index) => [
|
|
35
|
+
`${index + 1}. ${playlist.title}`,
|
|
36
|
+
` ${playlist.url}`,
|
|
37
|
+
]),
|
|
38
|
+
...(mayHaveMore ? ['', 'Raise limit to list more.'] : []),
|
|
39
|
+
'',
|
|
40
|
+
'Pass a playlist URL to fetch_videos or digest_playlist.',
|
|
41
|
+
];
|
|
42
|
+
return toolResult(lines.join('\n'), structured);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=list-channel-playlists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-channel-playlists.js","sourceRoot":"","sources":["../../src/tools/list-channel-playlists.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE5F,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,CAAC,2EAA2E,CAAC;IACxF,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,qBAAqB,CAAC;SAC1B,OAAO,CAAC,aAAa,CAAC;SACtB,QAAQ,CACP,qCAAqC,qBAAqB,cAAc,aAAa,EAAE,CACxF;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACvB,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;IAC1F,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;CACrF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,IAGjD;IACC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,oBAAoB,CACnF,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,KAAK,CACX,CAAC;IAEF,MAAM,UAAU,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IAE/F,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAC,GAAG,WAAW,2BAA2B,EAAE,UAAU,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,GAAG,WAAW,KAAK,SAAS,CAAC,MAAM,YAAY;QAC/C,EAAE;QACF,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,GAAG,KAAK,GAAG,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE;YACjC,MAAM,QAAQ,CAAC,GAAG,EAAE;SACrB,CAAC;QACF,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,EAAE;QACF,yDAAyD;KAC1D,CAAC;IAEF,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -59,7 +59,7 @@ export declare const queryCommentsOutputSchema: {
|
|
|
59
59
|
reason: z.ZodEnum<["COMPLETE", "CAP_REACHED", "BUDGET_SPENT", "RATE_LIMITED", "CANCELLED", "TIMEOUT", "SOURCE_REFUSED", "COMMENTS_DISABLED", "SOURCE_SILENT", "PARTIAL_ERROR", "NOT_ATTEMPTED"]>;
|
|
60
60
|
have: z.ZodNumber;
|
|
61
61
|
expected: z.ZodOptional<z.ZodNumber>;
|
|
62
|
-
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted"]>>;
|
|
62
|
+
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted", "store:catalog"]>>;
|
|
63
63
|
ranToExhaustion: z.ZodOptional<z.ZodBoolean>;
|
|
64
64
|
source: z.ZodString;
|
|
65
65
|
harvestedAt: z.ZodString;
|
|
@@ -69,33 +69,33 @@ export declare const queryCommentsOutputSchema: {
|
|
|
69
69
|
resumeToken: z.ZodOptional<z.ZodString>;
|
|
70
70
|
note: z.ZodOptional<z.ZodString>;
|
|
71
71
|
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
source: string;
|
|
72
73
|
have: number;
|
|
73
74
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
74
75
|
targetId: string;
|
|
75
76
|
complete: boolean;
|
|
76
77
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
77
|
-
source: string;
|
|
78
78
|
harvestedAt: string;
|
|
79
79
|
expected?: number | undefined;
|
|
80
80
|
note?: string | undefined;
|
|
81
81
|
ranToExhaustion?: boolean | undefined;
|
|
82
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
82
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
83
83
|
staleAfter?: string | undefined;
|
|
84
84
|
limitApplied?: number | undefined;
|
|
85
85
|
sortApplied?: "top" | "new" | undefined;
|
|
86
86
|
resumeToken?: string | undefined;
|
|
87
87
|
}, {
|
|
88
|
+
source: string;
|
|
88
89
|
have: number;
|
|
89
90
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
90
91
|
targetId: string;
|
|
91
92
|
complete: boolean;
|
|
92
93
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
93
|
-
source: string;
|
|
94
94
|
harvestedAt: string;
|
|
95
95
|
expected?: number | undefined;
|
|
96
96
|
note?: string | undefined;
|
|
97
97
|
ranToExhaustion?: boolean | undefined;
|
|
98
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
98
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
99
99
|
staleAfter?: string | undefined;
|
|
100
100
|
limitApplied?: number | undefined;
|
|
101
101
|
sortApplied?: "top" | "new" | undefined;
|
|
@@ -59,7 +59,7 @@ export declare const queryVideosOutputSchema: {
|
|
|
59
59
|
reason: z.ZodEnum<["COMPLETE", "CAP_REACHED", "BUDGET_SPENT", "RATE_LIMITED", "CANCELLED", "TIMEOUT", "SOURCE_REFUSED", "COMMENTS_DISABLED", "SOURCE_SILENT", "PARTIAL_ERROR", "NOT_ATTEMPTED"]>;
|
|
60
60
|
have: z.ZodNumber;
|
|
61
61
|
expected: z.ZodOptional<z.ZodNumber>;
|
|
62
|
-
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted"]>>;
|
|
62
|
+
expectedSource: z.ZodOptional<z.ZodEnum<["youtube:comment_count", "youtube:playlist_count", "source-exhausted", "store:catalog"]>>;
|
|
63
63
|
ranToExhaustion: z.ZodOptional<z.ZodBoolean>;
|
|
64
64
|
source: z.ZodString;
|
|
65
65
|
harvestedAt: z.ZodString;
|
|
@@ -69,33 +69,33 @@ export declare const queryVideosOutputSchema: {
|
|
|
69
69
|
resumeToken: z.ZodOptional<z.ZodString>;
|
|
70
70
|
note: z.ZodOptional<z.ZodString>;
|
|
71
71
|
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
source: string;
|
|
72
73
|
have: number;
|
|
73
74
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
74
75
|
targetId: string;
|
|
75
76
|
complete: boolean;
|
|
76
77
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
77
|
-
source: string;
|
|
78
78
|
harvestedAt: string;
|
|
79
79
|
expected?: number | undefined;
|
|
80
80
|
note?: string | undefined;
|
|
81
81
|
ranToExhaustion?: boolean | undefined;
|
|
82
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
82
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
83
83
|
staleAfter?: string | undefined;
|
|
84
84
|
limitApplied?: number | undefined;
|
|
85
85
|
sortApplied?: "top" | "new" | undefined;
|
|
86
86
|
resumeToken?: string | undefined;
|
|
87
87
|
}, {
|
|
88
|
+
source: string;
|
|
88
89
|
have: number;
|
|
89
90
|
scope: "channel-catalog" | "video-details" | "video-comments";
|
|
90
91
|
targetId: string;
|
|
91
92
|
complete: boolean;
|
|
92
93
|
reason: "RATE_LIMITED" | "TIMEOUT" | "CANCELLED" | "COMPLETE" | "CAP_REACHED" | "BUDGET_SPENT" | "SOURCE_REFUSED" | "COMMENTS_DISABLED" | "SOURCE_SILENT" | "PARTIAL_ERROR" | "NOT_ATTEMPTED";
|
|
93
|
-
source: string;
|
|
94
94
|
harvestedAt: string;
|
|
95
95
|
expected?: number | undefined;
|
|
96
96
|
note?: string | undefined;
|
|
97
97
|
ranToExhaustion?: boolean | undefined;
|
|
98
|
-
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | undefined;
|
|
98
|
+
expectedSource?: "youtube:playlist_count" | "source-exhausted" | "youtube:comment_count" | "store:catalog" | undefined;
|
|
99
99
|
staleAfter?: string | undefined;
|
|
100
100
|
limitApplied?: number | undefined;
|
|
101
101
|
sortApplied?: "top" | "new" | undefined;
|