@liorium/youtube-omni-mcp 0.1.2 → 0.2.2
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/.env.example +3 -2
- package/CHANGELOG.md +21 -0
- package/README.md +38 -10
- package/dist/src/config.d.ts +3 -0
- package/dist/src/config.js +4 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/core/errors.d.ts +3 -0
- package/dist/src/core/errors.js +2 -1
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/risk.d.ts +2 -0
- package/dist/src/core/risk.js +19 -3
- package/dist/src/core/risk.js.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/providers/mongo-cache-provider.d.ts +82 -0
- package/dist/src/providers/mongo-cache-provider.js +118 -0
- package/dist/src/providers/mongo-cache-provider.js.map +1 -0
- package/dist/src/providers/transcript-provider.d.ts +24 -0
- package/dist/src/providers/transcript-provider.js +9 -1
- package/dist/src/providers/transcript-provider.js.map +1 -1
- package/dist/src/providers/youtube-data-api.d.ts +65 -1
- package/dist/src/providers/youtube-data-api.js +108 -1
- package/dist/src/providers/youtube-data-api.js.map +1 -1
- package/dist/src/schemas/channel.d.ts +1 -1
- package/dist/src/schemas/common.d.ts +1 -1
- package/dist/src/schemas/discovery.d.ts +2 -2
- package/dist/src/schemas/index.d.ts +2 -0
- package/dist/src/schemas/index.js +2 -0
- package/dist/src/schemas/index.js.map +1 -1
- package/dist/src/schemas/operations.d.ts +50 -0
- package/dist/src/schemas/operations.js +41 -0
- package/dist/src/schemas/operations.js.map +1 -0
- package/dist/src/schemas/research.d.ts +37 -0
- package/dist/src/schemas/research.js +28 -0
- package/dist/src/schemas/research.js.map +1 -0
- package/dist/src/schemas/video.d.ts +1 -1
- package/dist/src/server.d.ts +13 -79
- package/dist/src/server.js +119 -6
- package/dist/src/server.js.map +1 -1
- package/dist/src/tools/operations.d.ts +14 -0
- package/dist/src/tools/operations.js +38 -0
- package/dist/src/tools/operations.js.map +1 -0
- package/dist/src/tools/research.d.ts +47 -0
- package/dist/src/tools/research.js +140 -0
- package/dist/src/tools/research.js.map +1 -0
- package/dist/src/tools/safety.js +1 -1
- package/dist/src/tools/safety.js.map +1 -1
- package/docs/safety-policy.md +30 -2
- package/docs/tool-schema.md +50 -1
- package/package.json +2 -1
package/.env.example
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Optional for public YouTube Data API reads
|
|
2
2
|
YOUTUBE_API_KEY=
|
|
3
3
|
|
|
4
|
-
# Optional cache/outlier provider,
|
|
4
|
+
# Optional cache/outlier provider. When enabled with MongoDB URI, public YouTube API responses are cached.
|
|
5
5
|
YOUTUBE_OMNI_ENABLE_OUTLIER=false
|
|
6
|
-
YOUTUBE_OMNI_MONGO_URI=
|
|
6
|
+
YOUTUBE_OMNI_MONGO_URI=mongodb://127.0.0.1:27018/youtube_omni_mcp
|
|
7
|
+
YOUTUBE_OMNI_CACHE_TTL_SECONDS=21600
|
|
7
8
|
|
|
8
9
|
# Safety defaults
|
|
9
10
|
YOUTUBE_OMNI_MAX_RESULTS=50
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.2 - 2026-05-14
|
|
4
|
+
|
|
5
|
+
- Document the dedicated local MongoDB backing-service names under the `youtube-omni-mcp` package prefix.
|
|
6
|
+
- Standardize local Docker resources as `youtube-omni-mcp-mongo:7`, `youtube-omni-mcp-mongo`, and `youtube-omni-mcp-mongo-data`.
|
|
7
|
+
- Keep the dedicated MongoDB connection on `127.0.0.1:27018/youtube_omni_mcp` with cache collection `youtube_omni_cache`.
|
|
8
|
+
|
|
9
|
+
## 0.2.1 - 2026-05-14
|
|
10
|
+
|
|
11
|
+
- Use the live YouTube Data API provider when `YOUTUBE_API_KEY` is configured instead of always using mock data.
|
|
12
|
+
- Add MongoDB cache provider activated by `YOUTUBE_OMNI_ENABLE_OUTLIER=true` plus `YOUTUBE_OMNI_MONGO_URI`.
|
|
13
|
+
- Add cache TTL configuration via `YOUTUBE_OMNI_CACHE_TTL_SECONDS` and document new-environment MCP setup.
|
|
14
|
+
- Keep mock provider fallback for safe schema/smoke testing when no API key is present.
|
|
15
|
+
|
|
16
|
+
## 0.2.0 - 2026-05-14
|
|
17
|
+
|
|
18
|
+
- Add five Creator Research tools: outlier video discovery, hook comparison, topic angle extraction, comment pain-point summarization, and video angle matrix generation.
|
|
19
|
+
- Add governed operation tool foundations for metadata, upload, thumbnail, playlist, comment moderation, and community post workflows.
|
|
20
|
+
- Keep operation tools hidden by default and dry-run-only when explicitly gated with `YOUTUBE_OMNI_ENABLE_WRITE_TOOLS=true` and `YOUTUBE_OMNI_DRY_RUN_WRITES=true`.
|
|
21
|
+
- Add concrete MCP schemas for research and gated operation tools.
|
|
22
|
+
- Update safety policy and capability reporting for the v0.2 phase.
|
|
23
|
+
|
|
3
24
|
## 0.1.2 - 2026-05-14
|
|
4
25
|
|
|
5
26
|
- Add concrete MCP `inputSchema` definitions for all v0 tools so agents can pass required arguments reliably.
|
package/README.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
`youtube-omni` is a full-scope YouTube Creator Intelligence + Operations + Analytics + Production MCP project.
|
|
4
4
|
|
|
5
|
-
Current implementation phase: **v0
|
|
5
|
+
Current implementation phase: **v0.2.1 live YouTube Data API + MongoDB cache foundation**.
|
|
6
6
|
|
|
7
|
-
## v0 boundary
|
|
7
|
+
## v0.2 default boundary
|
|
8
8
|
|
|
9
|
-
Enabled
|
|
9
|
+
Enabled by default:
|
|
10
10
|
|
|
11
11
|
- public discovery/search
|
|
12
12
|
- video details/comparison
|
|
@@ -14,6 +14,7 @@ Enabled in v0:
|
|
|
14
14
|
- transcript segments/full text/structure analysis
|
|
15
15
|
- comments read/summarize
|
|
16
16
|
- research brief drafts
|
|
17
|
+
- Creator Research synthesis tools
|
|
17
18
|
- safety/capability reporting
|
|
18
19
|
|
|
19
20
|
Locked for later phases, but part of final scope:
|
|
@@ -29,8 +30,9 @@ Locked for later phases, but part of final scope:
|
|
|
29
30
|
|
|
30
31
|
## Safety defaults
|
|
31
32
|
|
|
32
|
-
- No write tools are exposed
|
|
33
|
-
- No download tools are exposed
|
|
33
|
+
- No write tools are exposed by default.
|
|
34
|
+
- No download tools are exposed by default.
|
|
35
|
+
- Operation tools are dry-run-only stubs when `YOUTUBE_OMNI_ENABLE_WRITE_TOOLS=true` and `YOUTUBE_OMNI_DRY_RUN_WRITES=true` are both set.
|
|
34
36
|
- Secrets must be supplied via environment variables and are never committed.
|
|
35
37
|
- Write/download/destructive namespaces remain environment-gated for later phases.
|
|
36
38
|
|
|
@@ -55,8 +57,11 @@ Use this shape in an `mcp.json`-style client configuration:
|
|
|
55
57
|
"env": {
|
|
56
58
|
"YOUTUBE_API_KEY": "YOUR_YOUTUBE_DATA_API_KEY",
|
|
57
59
|
"YOUTUBE_OMNI_MAX_RESULTS": "50",
|
|
58
|
-
"YOUTUBE_OMNI_ENABLE_OUTLIER": "
|
|
60
|
+
"YOUTUBE_OMNI_ENABLE_OUTLIER": "true",
|
|
61
|
+
"YOUTUBE_OMNI_MONGO_URI": "mongodb://127.0.0.1:27018/youtube_omni_mcp",
|
|
62
|
+
"YOUTUBE_OMNI_CACHE_TTL_SECONDS": "21600",
|
|
59
63
|
"YOUTUBE_OMNI_ENABLE_WRITE_TOOLS": "false",
|
|
64
|
+
"YOUTUBE_OMNI_DRY_RUN_WRITES": "false",
|
|
60
65
|
"YOUTUBE_OMNI_ENABLE_DOWNLOAD_TOOLS": "false",
|
|
61
66
|
"YOUTUBE_OMNI_ENABLE_DESTRUCTIVE_TOOLS": "false"
|
|
62
67
|
}
|
|
@@ -69,7 +74,30 @@ For local development before publishing, use a packed tarball:
|
|
|
69
74
|
|
|
70
75
|
```bash
|
|
71
76
|
npm pack
|
|
72
|
-
npx -y ./liorium-youtube-omni-mcp-0.1.
|
|
77
|
+
npx -y ./liorium-youtube-omni-mcp-0.2.1.tgz
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## MongoDB cache mode
|
|
81
|
+
|
|
82
|
+
For a new Hermes/MCP environment, set both the flag and the URI:
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
YOUTUBE_OMNI_ENABLE_OUTLIER: 'true'
|
|
86
|
+
YOUTUBE_OMNI_MONGO_URI: mongodb://127.0.0.1:27018/youtube_omni_mcp
|
|
87
|
+
YOUTUBE_OMNI_CACHE_TTL_SECONDS: '21600'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
When `YOUTUBE_API_KEY` is present, youtube-omni uses the live YouTube Data API provider. When Mongo cache mode is also enabled, public Data API reads are wrapped by a MongoDB cache (`youtube_omni_cache` collection) so repeated research/planning calls reuse previous results instead of spending quota again. Without `YOUTUBE_API_KEY`, the server falls back to the mock provider for safe schema/smoke testing.
|
|
91
|
+
|
|
92
|
+
For local Docker-backed deployments, keep resource names under the package prefix:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
image: youtube-omni-mcp-mongo:7
|
|
96
|
+
container: youtube-omni-mcp-mongo
|
|
97
|
+
volume: youtube-omni-mcp-mongo-data
|
|
98
|
+
port: 127.0.0.1:27018 -> 27017
|
|
99
|
+
db: youtube_omni_mcp
|
|
100
|
+
collection: youtube_omni_cache
|
|
73
101
|
```
|
|
74
102
|
|
|
75
103
|
## Development
|
|
@@ -93,7 +121,7 @@ All research/specification documents are under `research/`. Implementation docs
|
|
|
93
121
|
|
|
94
122
|
Key docs:
|
|
95
123
|
|
|
96
|
-
- `docs/v0-spec.md` —
|
|
97
|
-
- `docs/tool-schema.md` — v0 tool contract
|
|
124
|
+
- `docs/v0-spec.md` — original read-only foundation boundary
|
|
125
|
+
- `docs/tool-schema.md` — v0.2 default and gated tool contract
|
|
98
126
|
- `docs/safety-policy.md` — risk gates and default locks
|
|
99
|
-
- `docs/v0.2-ac-plan.md` —
|
|
127
|
+
- `docs/v0.2-ac-plan.md` — implementation plan for Creator Research + governed write foundations
|
package/dist/src/config.d.ts
CHANGED
|
@@ -4,7 +4,10 @@ export interface YoutubeOmniConfig {
|
|
|
4
4
|
mongoUri?: string;
|
|
5
5
|
maxResults: number;
|
|
6
6
|
enableWriteTools: boolean;
|
|
7
|
+
dryRunWrites: boolean;
|
|
8
|
+
approvalAuditPath?: string;
|
|
7
9
|
enableDownloadTools: boolean;
|
|
10
|
+
cacheTtlSeconds: number;
|
|
8
11
|
}
|
|
9
12
|
export declare function loadConfig(env?: NodeJS.ProcessEnv): YoutubeOmniConfig;
|
|
10
13
|
export declare function redactedConfig(config: YoutubeOmniConfig): Record<string, unknown>;
|
package/dist/src/config.js
CHANGED
|
@@ -6,7 +6,10 @@ export function loadConfig(env = process.env) {
|
|
|
6
6
|
mongoUri: env.YOUTUBE_OMNI_MONGO_URI,
|
|
7
7
|
maxResults: Number(env.YOUTUBE_OMNI_MAX_RESULTS ?? 50),
|
|
8
8
|
enableWriteTools: env.YOUTUBE_OMNI_ENABLE_WRITE_TOOLS === 'true',
|
|
9
|
-
|
|
9
|
+
dryRunWrites: env.YOUTUBE_OMNI_DRY_RUN_WRITES === 'true',
|
|
10
|
+
approvalAuditPath: env.YOUTUBE_OMNI_APPROVAL_AUDIT_PATH,
|
|
11
|
+
enableDownloadTools: env.YOUTUBE_OMNI_ENABLE_DOWNLOAD_TOOLS === 'true',
|
|
12
|
+
cacheTtlSeconds: Number(env.YOUTUBE_OMNI_CACHE_TTL_SECONDS ?? 21600)
|
|
10
13
|
};
|
|
11
14
|
}
|
|
12
15
|
export function redactedConfig(config) {
|
package/dist/src/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAcpD,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,OAAO;QACL,aAAa,EAAE,GAAG,CAAC,eAAe;QAClC,aAAa,EAAE,GAAG,CAAC,2BAA2B,KAAK,MAAM;QACzD,QAAQ,EAAE,GAAG,CAAC,sBAAsB;QACpC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE,CAAC;QACtD,gBAAgB,EAAE,GAAG,CAAC,+BAA+B,KAAK,MAAM;QAChE,YAAY,EAAE,GAAG,CAAC,2BAA2B,KAAK,MAAM;QACxD,iBAAiB,EAAE,GAAG,CAAC,gCAAgC;QACvD,mBAAmB,EAAE,GAAG,CAAC,kCAAkC,KAAK,MAAM;QACtE,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,8BAA8B,IAAI,KAAK,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAyB;IACtD,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -35,6 +35,9 @@ export declare const YOUTUBE_OMNI_ERRORS: {
|
|
|
35
35
|
readonly SAFETY_BLOCKED: {
|
|
36
36
|
readonly retryable: false;
|
|
37
37
|
};
|
|
38
|
+
readonly APPROVAL_REQUIRED_OR_WRITE_DISABLED: {
|
|
39
|
+
readonly retryable: false;
|
|
40
|
+
};
|
|
38
41
|
};
|
|
39
42
|
export type YoutubeOmniErrorCode = keyof typeof YOUTUBE_OMNI_ERRORS;
|
|
40
43
|
export declare class YoutubeOmniError extends Error {
|
package/dist/src/core/errors.js
CHANGED
|
@@ -10,7 +10,8 @@ export const YOUTUBE_OMNI_ERRORS = {
|
|
|
10
10
|
COMMENTS_DISABLED: { retryable: false },
|
|
11
11
|
UNSUPPORTED_REGION: { retryable: false },
|
|
12
12
|
PROVIDER_ERROR: { retryable: true },
|
|
13
|
-
SAFETY_BLOCKED: { retryable: false }
|
|
13
|
+
SAFETY_BLOCKED: { retryable: false },
|
|
14
|
+
APPROVAL_REQUIRED_OR_WRITE_DISABLED: { retryable: false }
|
|
14
15
|
};
|
|
15
16
|
export class YoutubeOmniError extends Error {
|
|
16
17
|
code;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,gBAAgB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACtC,uBAAuB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IAC7C,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACnC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IACnC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IACjC,eAAe,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACrC,iBAAiB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACvC,sBAAsB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IAC5C,iBAAiB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACvC,kBAAkB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACxC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IACnC,cAAc,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,gBAAgB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACtC,uBAAuB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IAC7C,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACnC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IACnC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IACjC,eAAe,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACrC,iBAAiB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACvC,sBAAsB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IAC5C,iBAAiB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACvC,kBAAkB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACxC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IACnC,cAAc,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;IACpC,mCAAmC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;CACjD,CAAC;AAIX,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAuB;IAC3B,SAAS,CAAU;IAE5B,YAAY,IAA0B,EAAE,OAAe;QACrD,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;IACvD,CAAC;CACF"}
|
package/dist/src/core/risk.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare const V0_LOCKED_PATTERNS: readonly ["upload", "update_video", "delete", "set_thumbnail", "reply_to_comment", "moderate", "publish", "download_video", "clip_segment", "revenue"];
|
|
2
|
+
export type RiskLabel = 'none' | 'low' | 'medium' | 'high' | 'destructive';
|
|
2
3
|
export interface ActionRisk {
|
|
4
|
+
risk: RiskLabel;
|
|
3
5
|
riskTier: 0 | 1 | 2 | 3 | 4 | 5;
|
|
4
6
|
authTier: 'none' | 'api_key' | 'oauth_readonly' | 'oauth_write' | 'hosted' | 'experimental';
|
|
5
7
|
allowedInV0: boolean;
|
package/dist/src/core/risk.js
CHANGED
|
@@ -13,19 +13,35 @@ export const V0_LOCKED_PATTERNS = [
|
|
|
13
13
|
export function isAllowedInV0(action) {
|
|
14
14
|
return !V0_LOCKED_PATTERNS.some((pattern) => action.includes(pattern));
|
|
15
15
|
}
|
|
16
|
+
function operationRisk(action) {
|
|
17
|
+
if (!action.includes('youtube.operations.'))
|
|
18
|
+
return undefined;
|
|
19
|
+
const destructive = ['delete_video', 'delete', 'remove'].some((pattern) => action.includes(pattern));
|
|
20
|
+
return {
|
|
21
|
+
risk: destructive ? 'destructive' : 'high',
|
|
22
|
+
riskTier: destructive ? 5 : 4,
|
|
23
|
+
authTier: 'oauth_write',
|
|
24
|
+
allowedInV0: false,
|
|
25
|
+
requiredControls: destructive ? ['approval', 'double_confirmation', 'audit'] : ['approval', 'preview', 'audit', 'dry_run']
|
|
26
|
+
};
|
|
27
|
+
}
|
|
16
28
|
export function classifyActionRisk(action) {
|
|
29
|
+
const operation = operationRisk(action);
|
|
30
|
+
if (operation)
|
|
31
|
+
return operation;
|
|
17
32
|
if (!isAllowedInV0(action)) {
|
|
18
33
|
const destructive = ['delete', 'download_video', 'clip_segment', 'revenue'].some((pattern) => action.includes(pattern));
|
|
19
34
|
return {
|
|
35
|
+
risk: destructive ? 'destructive' : 'high',
|
|
20
36
|
riskTier: destructive ? 5 : 4,
|
|
21
37
|
authTier: action.includes('download') || action.includes('clip') ? 'experimental' : 'oauth_write',
|
|
22
38
|
allowedInV0: false,
|
|
23
39
|
requiredControls: destructive ? ['approval', 'double_confirmation', 'audit'] : ['approval', 'preview', 'audit']
|
|
24
40
|
};
|
|
25
41
|
}
|
|
26
|
-
if (action.includes('transcript') || action.includes('comments') || action.includes('planning')) {
|
|
27
|
-
return { riskTier: 1, authTier: 'api_key', allowedInV0: true, requiredControls: ['rate_limit', 'privacy_warning'] };
|
|
42
|
+
if (action.includes('transcript') || action.includes('comments') || action.includes('planning') || action.includes('research')) {
|
|
43
|
+
return { risk: 'low', riskTier: 1, authTier: 'api_key', allowedInV0: true, requiredControls: ['rate_limit', 'privacy_warning'] };
|
|
28
44
|
}
|
|
29
|
-
return { riskTier: 0, authTier: 'api_key', allowedInV0: true, requiredControls: ['rate_limit'] };
|
|
45
|
+
return { risk: 'none', riskTier: 0, authTier: 'api_key', allowedInV0: true, requiredControls: ['rate_limit'] };
|
|
30
46
|
}
|
|
31
47
|
//# sourceMappingURL=risk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"risk.js","sourceRoot":"","sources":["../../../src/core/risk.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ;IACR,cAAc;IACd,QAAQ;IACR,eAAe;IACf,kBAAkB;IAClB,UAAU;IACV,SAAS;IACT,gBAAgB;IAChB,cAAc;IACd,SAAS;CACD,CAAC;
|
|
1
|
+
{"version":3,"file":"risk.js","sourceRoot":"","sources":["../../../src/core/risk.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -21,7 +21,7 @@ rl.on('line', async (line) => {
|
|
|
21
21
|
try {
|
|
22
22
|
const request = JSON.parse(line);
|
|
23
23
|
if (request.method === 'initialize') {
|
|
24
|
-
respond(request.id, { protocolVersion: '2024-11-05', capabilities: { tools: {} }, serverInfo: { name: 'youtube-omni-mcp', version: '0.
|
|
24
|
+
respond(request.id, { protocolVersion: '2024-11-05', capabilities: { tools: {} }, serverInfo: { name: 'youtube-omni-mcp', version: '0.2.2' } });
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
if (request.method === 'tools/list') {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { ProviderHealth, YoutubeOmniProvider } from './types.js';
|
|
2
|
+
export interface CacheStore {
|
|
3
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
4
|
+
set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
|
|
5
|
+
close?(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare class MongoCacheProvider implements YoutubeOmniProvider {
|
|
8
|
+
readonly upstream: YoutubeOmniProvider;
|
|
9
|
+
private readonly store;
|
|
10
|
+
private readonly ttlSeconds;
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
authTier: import("../core/envelope.js").AuthTier;
|
|
14
|
+
capabilities: string[];
|
|
15
|
+
constructor(upstream: YoutubeOmniProvider, store: CacheStore, ttlSeconds?: number);
|
|
16
|
+
isConfigured(): boolean;
|
|
17
|
+
healthCheck(): Promise<ProviderHealth>;
|
|
18
|
+
private cached;
|
|
19
|
+
searchVideos(input: {
|
|
20
|
+
query: string;
|
|
21
|
+
maxResults: number;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
videos: any[];
|
|
24
|
+
}>;
|
|
25
|
+
searchChannels(input: {
|
|
26
|
+
query: string;
|
|
27
|
+
maxResults: number;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
channels: any[];
|
|
30
|
+
}>;
|
|
31
|
+
getTrendingVideos(input: {
|
|
32
|
+
regionCode: string;
|
|
33
|
+
categoryId?: string;
|
|
34
|
+
maxResults: number;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
videos: any[];
|
|
37
|
+
}>;
|
|
38
|
+
getVideoCategories(input: {
|
|
39
|
+
regionCode: string;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
regionCode: string;
|
|
42
|
+
categories: any[];
|
|
43
|
+
}>;
|
|
44
|
+
getVideoDetails(input: {
|
|
45
|
+
videoIds: string[];
|
|
46
|
+
includeTags?: boolean;
|
|
47
|
+
descriptionDetail?: string;
|
|
48
|
+
}): Promise<{
|
|
49
|
+
videos: any[];
|
|
50
|
+
}>;
|
|
51
|
+
getChannelStatistics(input: {
|
|
52
|
+
channelIds: string[];
|
|
53
|
+
}): Promise<{
|
|
54
|
+
channels: any[];
|
|
55
|
+
}>;
|
|
56
|
+
getChannelTopVideos(input: {
|
|
57
|
+
channelId: string;
|
|
58
|
+
maxResults: number;
|
|
59
|
+
}): Promise<{
|
|
60
|
+
channelId: string;
|
|
61
|
+
videos: any[];
|
|
62
|
+
}>;
|
|
63
|
+
getVideoComments(input: {
|
|
64
|
+
videoId: string;
|
|
65
|
+
maxResults: number;
|
|
66
|
+
maxReplies: number;
|
|
67
|
+
}): Promise<{
|
|
68
|
+
videoId: string;
|
|
69
|
+
comments: any[];
|
|
70
|
+
}>;
|
|
71
|
+
}
|
|
72
|
+
export declare class MongoCacheStore implements CacheStore {
|
|
73
|
+
private readonly uri;
|
|
74
|
+
private readonly dbName;
|
|
75
|
+
private readonly collectionName;
|
|
76
|
+
private clientPromise?;
|
|
77
|
+
constructor(uri: string, dbName?: string, collectionName?: string);
|
|
78
|
+
private collection;
|
|
79
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
80
|
+
set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
|
|
81
|
+
close(): Promise<void>;
|
|
82
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
function stableStringify(value) {
|
|
2
|
+
if (Array.isArray(value))
|
|
3
|
+
return `[${value.map(stableStringify).join(',')}]`;
|
|
4
|
+
if (value && typeof value === 'object') {
|
|
5
|
+
return `{${Object.entries(value)
|
|
6
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
7
|
+
.map(([key, val]) => `${JSON.stringify(key)}:${stableStringify(val)}`)
|
|
8
|
+
.join(',')}}`;
|
|
9
|
+
}
|
|
10
|
+
return JSON.stringify(value);
|
|
11
|
+
}
|
|
12
|
+
function cacheKey(providerId, method, input) {
|
|
13
|
+
return `youtube-omni:v1:${providerId}:${method}:${stableStringify(input)}`;
|
|
14
|
+
}
|
|
15
|
+
export class MongoCacheProvider {
|
|
16
|
+
upstream;
|
|
17
|
+
store;
|
|
18
|
+
ttlSeconds;
|
|
19
|
+
id = 'mongo_cache';
|
|
20
|
+
name = 'MongoDB cached YouTube provider';
|
|
21
|
+
authTier;
|
|
22
|
+
capabilities;
|
|
23
|
+
constructor(upstream, store, ttlSeconds = 6 * 60 * 60) {
|
|
24
|
+
this.upstream = upstream;
|
|
25
|
+
this.store = store;
|
|
26
|
+
this.ttlSeconds = ttlSeconds;
|
|
27
|
+
this.authTier = upstream.authTier;
|
|
28
|
+
this.capabilities = [...upstream.capabilities];
|
|
29
|
+
}
|
|
30
|
+
isConfigured() { return this.upstream.isConfigured(); }
|
|
31
|
+
async healthCheck() {
|
|
32
|
+
const upstream = await this.upstream.healthCheck();
|
|
33
|
+
return {
|
|
34
|
+
provider: this.id,
|
|
35
|
+
configured: this.isConfigured(),
|
|
36
|
+
authTier: this.authTier,
|
|
37
|
+
capabilities: this.capabilities,
|
|
38
|
+
warnings: [`Caching upstream provider: ${upstream.provider}`, ...upstream.warnings]
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async cached(method, input, fetcher) {
|
|
42
|
+
const key = cacheKey(this.upstream.id, method, input);
|
|
43
|
+
const cached = await this.store.get(key);
|
|
44
|
+
if (cached !== undefined)
|
|
45
|
+
return cached;
|
|
46
|
+
const fresh = await fetcher();
|
|
47
|
+
await this.store.set(key, fresh, this.ttlSeconds);
|
|
48
|
+
return fresh;
|
|
49
|
+
}
|
|
50
|
+
async searchVideos(input) {
|
|
51
|
+
return this.cached('searchVideos', input, () => this.upstream.searchVideos(input));
|
|
52
|
+
}
|
|
53
|
+
async searchChannels(input) {
|
|
54
|
+
return this.cached('searchChannels', input, () => this.upstream.searchChannels(input));
|
|
55
|
+
}
|
|
56
|
+
async getTrendingVideos(input) {
|
|
57
|
+
return this.cached('getTrendingVideos', input, () => this.upstream.getTrendingVideos(input));
|
|
58
|
+
}
|
|
59
|
+
async getVideoCategories(input) {
|
|
60
|
+
return this.cached('getVideoCategories', input, () => this.upstream.getVideoCategories(input));
|
|
61
|
+
}
|
|
62
|
+
async getVideoDetails(input) {
|
|
63
|
+
return this.cached('getVideoDetails', input, () => this.upstream.getVideoDetails(input));
|
|
64
|
+
}
|
|
65
|
+
async getChannelStatistics(input) {
|
|
66
|
+
return this.cached('getChannelStatistics', input, () => this.upstream.getChannelStatistics(input));
|
|
67
|
+
}
|
|
68
|
+
async getChannelTopVideos(input) {
|
|
69
|
+
return this.cached('getChannelTopVideos', input, () => this.upstream.getChannelTopVideos(input));
|
|
70
|
+
}
|
|
71
|
+
async getVideoComments(input) {
|
|
72
|
+
return this.cached('getVideoComments', input, () => this.upstream.getVideoComments(input));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export class MongoCacheStore {
|
|
76
|
+
uri;
|
|
77
|
+
dbName;
|
|
78
|
+
collectionName;
|
|
79
|
+
clientPromise;
|
|
80
|
+
constructor(uri, dbName = databaseNameFromUri(uri), collectionName = 'youtube_omni_cache') {
|
|
81
|
+
this.uri = uri;
|
|
82
|
+
this.dbName = dbName;
|
|
83
|
+
this.collectionName = collectionName;
|
|
84
|
+
}
|
|
85
|
+
async collection() {
|
|
86
|
+
if (!this.clientPromise) {
|
|
87
|
+
const { MongoClient } = await import('mongodb');
|
|
88
|
+
const client = new MongoClient(this.uri, { serverSelectionTimeoutMS: 5000 });
|
|
89
|
+
this.clientPromise = client.connect().then(() => client);
|
|
90
|
+
}
|
|
91
|
+
const client = await this.clientPromise;
|
|
92
|
+
const collection = client.db(this.dbName).collection(this.collectionName);
|
|
93
|
+
await collection.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
94
|
+
return collection;
|
|
95
|
+
}
|
|
96
|
+
async get(key) {
|
|
97
|
+
const hit = await (await this.collection()).findOne({ _id: key, $or: [{ expiresAt: { $exists: false } }, { expiresAt: { $gt: new Date() } }] });
|
|
98
|
+
return hit?.value;
|
|
99
|
+
}
|
|
100
|
+
async set(key, value, ttlSeconds = 6 * 60 * 60) {
|
|
101
|
+
const expiresAt = new Date(Date.now() + ttlSeconds * 1000);
|
|
102
|
+
await (await this.collection()).updateOne({ _id: key }, { $set: { value, expiresAt, updatedAt: new Date() }, $setOnInsert: { createdAt: new Date() } }, { upsert: true });
|
|
103
|
+
}
|
|
104
|
+
async close() {
|
|
105
|
+
const client = await this.clientPromise;
|
|
106
|
+
await client?.close();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function databaseNameFromUri(uri) {
|
|
110
|
+
try {
|
|
111
|
+
const parsed = new URL(uri);
|
|
112
|
+
return parsed.pathname.replace(/^\//, '') || 'youtube_mcp';
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return 'youtube_mcp';
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=mongo-cache-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongo-cache-provider.js","sourceRoot":"","sources":["../../../src/providers/mongo-cache-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,4 +6,28 @@ export declare class TranscriptProvider implements YoutubeOmniProvider {
|
|
|
6
6
|
capabilities: string[];
|
|
7
7
|
isConfigured(): boolean;
|
|
8
8
|
healthCheck(): Promise<ProviderHealth>;
|
|
9
|
+
getTranscriptSegments(input: {
|
|
10
|
+
videoIds: string[];
|
|
11
|
+
lang: string;
|
|
12
|
+
format: 'key_segments';
|
|
13
|
+
}): Promise<{
|
|
14
|
+
transcripts: {
|
|
15
|
+
videoId: string;
|
|
16
|
+
language: string;
|
|
17
|
+
format: "key_segments";
|
|
18
|
+
intro: string;
|
|
19
|
+
outro: string;
|
|
20
|
+
availability: string;
|
|
21
|
+
}[];
|
|
22
|
+
}>;
|
|
23
|
+
getTranscriptFullText(input: {
|
|
24
|
+
videoId: string;
|
|
25
|
+
lang: string;
|
|
26
|
+
maxChars: number;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
videoId: string;
|
|
29
|
+
language: string;
|
|
30
|
+
text: string;
|
|
31
|
+
truncated: boolean;
|
|
32
|
+
}>;
|
|
9
33
|
}
|
|
@@ -4,6 +4,14 @@ export class TranscriptProvider {
|
|
|
4
4
|
authTier = 'none';
|
|
5
5
|
capabilities = ['transcript'];
|
|
6
6
|
isConfigured() { return true; }
|
|
7
|
-
async healthCheck() {
|
|
7
|
+
async healthCheck() {
|
|
8
|
+
return { provider: this.id, configured: true, authTier: this.authTier, capabilities: this.capabilities, warnings: ['Transcript provider returns unavailable placeholders until a real transcript adapter is configured'] };
|
|
9
|
+
}
|
|
10
|
+
async getTranscriptSegments(input) {
|
|
11
|
+
return { transcripts: input.videoIds.map((videoId) => ({ videoId, language: input.lang, format: input.format, intro: '', outro: '', availability: 'unavailable' })) };
|
|
12
|
+
}
|
|
13
|
+
async getTranscriptFullText(input) {
|
|
14
|
+
return { videoId: input.videoId, language: input.lang, text: '', truncated: false };
|
|
15
|
+
}
|
|
8
16
|
}
|
|
9
17
|
//# sourceMappingURL=transcript-provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript-provider.js","sourceRoot":"","sources":["../../../src/providers/transcript-provider.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,kBAAkB;IAC7B,EAAE,GAAG,wBAAwB,CAAC;IAC9B,IAAI,GAAG,iCAAiC,CAAC;IACzC,QAAQ,GAAG,MAAe,CAAC;IAC3B,YAAY,GAAG,CAAC,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"transcript-provider.js","sourceRoot":"","sources":["../../../src/providers/transcript-provider.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,kBAAkB;IAC7B,EAAE,GAAG,wBAAwB,CAAC;IAC9B,IAAI,GAAG,iCAAiC,CAAC;IACzC,QAAQ,GAAG,MAAe,CAAC;IAC3B,YAAY,GAAG,CAAC,YAAY,CAAC,CAAC;IAE9B,YAAY,KAAc,OAAO,IAAI,CAAC,CAAC,CAAC;IAExC,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,oGAAoG,CAAC,EAAE,CAAC;IAC7N,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,KAAmE;QAC7F,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC;IACxK,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,KAA0D;QACpF,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACtF,CAAC;CACF"}
|
|
@@ -1,11 +1,75 @@
|
|
|
1
1
|
import type { ProviderHealth, YoutubeOmniProvider } from './types.js';
|
|
2
|
+
type FetchLike = typeof fetch;
|
|
2
3
|
export declare class YoutubeDataApiProvider implements YoutubeOmniProvider {
|
|
3
4
|
id: string;
|
|
4
5
|
name: string;
|
|
5
6
|
authTier: "api_key";
|
|
6
7
|
capabilities: string[];
|
|
7
8
|
private readonly apiKey?;
|
|
8
|
-
|
|
9
|
+
private readonly fetchImpl;
|
|
10
|
+
constructor(apiKey?: string, fetchImpl?: FetchLike);
|
|
9
11
|
isConfigured(): boolean;
|
|
10
12
|
healthCheck(): Promise<ProviderHealth>;
|
|
13
|
+
private get;
|
|
14
|
+
searchVideos(input: {
|
|
15
|
+
query: string;
|
|
16
|
+
maxResults: number;
|
|
17
|
+
order?: string;
|
|
18
|
+
videoDuration?: string;
|
|
19
|
+
recency?: string;
|
|
20
|
+
regionCode?: string;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
videos: any;
|
|
23
|
+
}>;
|
|
24
|
+
searchChannels(input: {
|
|
25
|
+
query: string;
|
|
26
|
+
maxResults: number;
|
|
27
|
+
regionCode?: string;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
channels: any;
|
|
30
|
+
}>;
|
|
31
|
+
getTrendingVideos(input: {
|
|
32
|
+
regionCode: string;
|
|
33
|
+
categoryId?: string;
|
|
34
|
+
maxResults: number;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
videos: any;
|
|
37
|
+
}>;
|
|
38
|
+
getVideoCategories(input: {
|
|
39
|
+
regionCode: string;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
regionCode: string;
|
|
42
|
+
categories: any;
|
|
43
|
+
}>;
|
|
44
|
+
getVideoDetails(input: {
|
|
45
|
+
videoIds: string[];
|
|
46
|
+
includeTags?: boolean;
|
|
47
|
+
descriptionDetail?: string;
|
|
48
|
+
}): Promise<{
|
|
49
|
+
videos: any;
|
|
50
|
+
}>;
|
|
51
|
+
getChannelStatistics(input: {
|
|
52
|
+
channelIds: string[];
|
|
53
|
+
}): Promise<{
|
|
54
|
+
channels: any;
|
|
55
|
+
}>;
|
|
56
|
+
getChannelTopVideos(input: {
|
|
57
|
+
channelId: string;
|
|
58
|
+
maxResults: number;
|
|
59
|
+
includeTags?: boolean;
|
|
60
|
+
descriptionDetail?: string;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
channelId: string;
|
|
63
|
+
videos: any;
|
|
64
|
+
}>;
|
|
65
|
+
getVideoComments(input: {
|
|
66
|
+
videoId: string;
|
|
67
|
+
maxResults: number;
|
|
68
|
+
maxReplies: number;
|
|
69
|
+
order?: string;
|
|
70
|
+
}): Promise<{
|
|
71
|
+
videoId: string;
|
|
72
|
+
comments: any;
|
|
73
|
+
}>;
|
|
11
74
|
}
|
|
75
|
+
export {};
|