@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.
Files changed (49) hide show
  1. package/.env.example +3 -2
  2. package/CHANGELOG.md +21 -0
  3. package/README.md +38 -10
  4. package/dist/src/config.d.ts +3 -0
  5. package/dist/src/config.js +4 -1
  6. package/dist/src/config.js.map +1 -1
  7. package/dist/src/core/errors.d.ts +3 -0
  8. package/dist/src/core/errors.js +2 -1
  9. package/dist/src/core/errors.js.map +1 -1
  10. package/dist/src/core/risk.d.ts +2 -0
  11. package/dist/src/core/risk.js +19 -3
  12. package/dist/src/core/risk.js.map +1 -1
  13. package/dist/src/index.js +1 -1
  14. package/dist/src/providers/mongo-cache-provider.d.ts +82 -0
  15. package/dist/src/providers/mongo-cache-provider.js +118 -0
  16. package/dist/src/providers/mongo-cache-provider.js.map +1 -0
  17. package/dist/src/providers/transcript-provider.d.ts +24 -0
  18. package/dist/src/providers/transcript-provider.js +9 -1
  19. package/dist/src/providers/transcript-provider.js.map +1 -1
  20. package/dist/src/providers/youtube-data-api.d.ts +65 -1
  21. package/dist/src/providers/youtube-data-api.js +108 -1
  22. package/dist/src/providers/youtube-data-api.js.map +1 -1
  23. package/dist/src/schemas/channel.d.ts +1 -1
  24. package/dist/src/schemas/common.d.ts +1 -1
  25. package/dist/src/schemas/discovery.d.ts +2 -2
  26. package/dist/src/schemas/index.d.ts +2 -0
  27. package/dist/src/schemas/index.js +2 -0
  28. package/dist/src/schemas/index.js.map +1 -1
  29. package/dist/src/schemas/operations.d.ts +50 -0
  30. package/dist/src/schemas/operations.js +41 -0
  31. package/dist/src/schemas/operations.js.map +1 -0
  32. package/dist/src/schemas/research.d.ts +37 -0
  33. package/dist/src/schemas/research.js +28 -0
  34. package/dist/src/schemas/research.js.map +1 -0
  35. package/dist/src/schemas/video.d.ts +1 -1
  36. package/dist/src/server.d.ts +13 -79
  37. package/dist/src/server.js +119 -6
  38. package/dist/src/server.js.map +1 -1
  39. package/dist/src/tools/operations.d.ts +14 -0
  40. package/dist/src/tools/operations.js +38 -0
  41. package/dist/src/tools/operations.js.map +1 -0
  42. package/dist/src/tools/research.d.ts +47 -0
  43. package/dist/src/tools/research.js +140 -0
  44. package/dist/src/tools/research.js.map +1 -0
  45. package/dist/src/tools/safety.js +1 -1
  46. package/dist/src/tools/safety.js.map +1 -1
  47. package/docs/safety-policy.md +30 -2
  48. package/docs/tool-schema.md +50 -1
  49. 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, disabled by default
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 read-only foundation**.
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 in v0:
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 in v0.
33
- - No download tools are exposed in v0.
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": "false",
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.2.tgz
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` — current read-only boundary
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` — next implementation plan for Creator Research + governed write foundations
127
+ - `docs/v0.2-ac-plan.md` — implementation plan for Creator Research + governed write foundations
@@ -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>;
@@ -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
- enableDownloadTools: env.YOUTUBE_OMNI_ENABLE_DOWNLOAD_TOOLS === 'true'
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) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWpD,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,mBAAmB,EAAE,GAAG,CAAC,kCAAkC,KAAK,MAAM;KACvE,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"}
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 {
@@ -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;CAC5B,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"}
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"}
@@ -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;
@@ -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;AASX,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACxH,OAAO;YACL,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;YACjG,WAAW,EAAE,KAAK;YAClB,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC;SAChH,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAChG,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC,EAAE,CAAC;IACtH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;AACnG,CAAC"}
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;AAYX,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,WAAW,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACrG,OAAO;QACL,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM;QAC1C,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,QAAQ,EAAE,aAAa;QACvB,WAAW,EAAE,KAAK;QAClB,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC;KAC3H,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACxH,OAAO;YACL,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM;YAC1C,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;YACjG,WAAW,EAAE,KAAK;YAClB,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC;SAChH,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/H,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC,EAAE,CAAC;IACnI,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;AACjH,CAAC"}
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.1.1' } });
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() { return { provider: this.id, configured: true, authTier: this.authTier, capabilities: this.capabilities, warnings: ['Placeholder provider returns TRANSCRIPT_UNAVAILABLE until a real transcript adapter is configured'] }; }
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;IAC9B,YAAY,KAAc,OAAO,IAAI,CAAC,CAAC,CAAC;IACxC,KAAK,CAAC,WAAW,KAA8B,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,mGAAmG,CAAC,EAAE,CAAC,CAAC,CAAC;CAC5Q"}
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
- constructor(apiKey?: string);
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 {};