owner-clone-ai-mcp 1.69.0 → 1.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/domains/slides.js CHANGED
@@ -6,27 +6,34 @@ const { callApi } = require('../lib/api');
6
6
  const tools = [
7
7
  {
8
8
  name: 'get_slide_schema',
9
- description: 'スライド作成のスキーマ情報(テンプレ種別20種・デザインテーマ13種・用途4種の一覧と説明)を取得します。create_slide_deck / update_slide_deck で deck JSON を組む前に一度確認してください。',
9
+ description: 'スライド作成のスキーマ情報(テンプレ種別23種・デザインテーマ13種・用途5種・スライド比率5種の一覧と説明)を取得します。create_slide_deck / update_slide_deck で deck JSON を組む前に一度確認してください。',
10
10
  annotations: { readOnlyHint: true },
11
11
  inputSchema: { type: 'object', properties: {}, required: [] },
12
12
  },
13
13
  {
14
14
  name: 'list_slide_decks',
15
- description: 'スライドデッキの一覧(ID・タイトル・枚数・テーマ・用途)を取得します。',
15
+ description: 'スライドデッキの一覧(ID・タイトル・枚数・テーマ・用途・カテゴリ名)を取得します。archived=true でアーカイブ済み一覧(ゴミ箱は含まれません)。',
16
16
  annotations: { readOnlyHint: true },
17
- inputSchema: { type: 'object', properties: {}, required: [] },
17
+ inputSchema: { type: 'object', properties: { archived: { type: 'boolean', description: 'true=アーカイブ済み一覧' } }, required: [] },
18
18
  },
19
19
  {
20
20
  name: 'get_slide_deck',
21
- description: 'スライドデッキの内容(全スライドのJSON)を取得します。deck.chapters が各スライド(kind=テンプレ種別)。',
21
+ description: 'スライドデッキの内容を取得します。text=全スライドのテキスト化(要約・内容の質問・引用にはこれを使う)。with_narration=true で各スライドの note(ナレーション原稿)込みの原稿を取得。deck.chapters=編集用JSON(kind=テンプレ種別・note=ナレーション原稿)。',
22
22
  annotations: { readOnlyHint: true },
23
- inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'デッキID(list_slide_decksで確認)' } }, required: ['id'] },
23
+ inputSchema: { type: 'object', properties: {
24
+ id: { type: 'string', description: 'デッキID(list_slide_decksで確認)' },
25
+ with_narration: { type: 'boolean', description: 'true=ナレーション込み原稿(text_with_narration)を返す(省略=ナレーションなし原稿)' },
26
+ }, required: ['id'] },
24
27
  },
25
28
  {
26
29
  name: 'generate_slide_deck',
27
30
  description: `ナレッジやテキストからAIがスライドデッキを自動設計して新規作成します(スライド作成機能の中核)。
28
- 生成後ユーザーは編集画面(/slides/デッキID)で微調整し、PDF/PPTX/画像に書き出せます。
29
- ◆ 用途: document=配布資料(資料だけで意味が通る密度) / lecture=講座 / vsl=セールス構成 / ad=広告(誇大表現を避ける)
31
+ 生成後ユーザーは編集画面(/slides/デッキID)で微調整し、PDF/PPTX/画像に書き出せます。共有・配布URLは share_slide_deck。
32
+ ◆ 一発で良いスライドを作るコツ:
33
+ - 用途を内容に合わせて選ぶ: document=配布資料(資料だけで意味が通る密度)/ lecture=講座・研修(目次→各論→まとめ)/ vsl=セールス(問題提起→解決策→実績→オファー→CTA)/ ad=広告(誇大表現を自動回避)/ free=構成の型を注入せず instructions を最優先
34
+ - 生成元は具体的に: 該当ナレッジ(複数/フォルダごと可)+テキスト併用可。元資料にない事実は創作されない
35
+ - instructions にトーン・必須スライド・構成の希望を書く(例: 経営者向けのトーンで/料金比較の表を入れて/最後に問い合わせCTA)
36
+ - slide_count_hint で分量制御(目安: 報告5-10枚・講座15-30枚・VSL 12-20枚)
30
37
  ◆ テーマ: light-clean(明るく清潔・既定) / dark-navy(信頼・テック) / warm-cream / mono-minimal / corporate / vivid-pop / elegant-gold(高級) / light-colorful / passion-red(VSL) / plain-doc(実務資料風) / paper-note / aurora-glass / gradient-pop`,
31
38
  annotations: { destructiveHint: false },
32
39
  inputSchema: {
@@ -35,11 +42,13 @@ const tools = [
35
42
  knowledge_item_ids: { type: 'array', items: { type: 'string' }, description: '生成元ナレッジID(複数可)' },
36
43
  knowledge_folder_ids: { type: 'array', items: { type: 'string' }, description: '生成元ナレッジフォルダID(サブフォルダ含む・複数可)' },
37
44
  text: { type: 'string', description: '生成元テキスト(ナレッジ指定と併用可)' },
38
- purpose: { type: 'string', enum: ['document', 'lecture', 'vsl', 'ad'], description: '用途(省略時 document)' },
45
+ format: { type: 'string', enum: ['wide', 'classic', 'square', 'vertical', 'a4'], description: 'スライド比率: wide=16:9(既定・省略可)/ classic=4:3 / square=1:1(SNS投稿) / vertical=9:19縦長(ショート動画/スマホ) / a4=A4縦(書籍・印刷資料)' },
46
+ purpose: { type: 'string', enum: ['document', 'lecture', 'vsl', 'ad', 'free'], description: '用途(省略時 document)' },
39
47
  theme: { type: 'string', description: 'デザインテーマID(省略時 light-clean)' },
40
48
  instructions: { type: 'string', description: '追加指示(例: 経営者向けのトーンで・料金比較の表を入れて)' },
41
49
  slide_count_hint: { type: 'number', description: '目安のスライド枚数' },
42
50
  title: { type: 'string', description: 'タイトル(省略時は表紙から自動)' },
51
+ include_narration: { type: 'boolean', description: 'true=各スライドに note(話し言葉のナレーション原稿・発表者ノート)も生成。VSL・動画化・登壇向けにおすすめ(省略=生成しない)' },
43
52
  },
44
53
  required: [],
45
54
  },
@@ -52,7 +61,7 @@ const tools = [
52
61
  type: 'object',
53
62
  properties: {
54
63
  title: { type: 'string' },
55
- purpose: { type: 'string', enum: ['document', 'lecture', 'vsl', 'ad'] },
64
+ purpose: { type: 'string', enum: ['document', 'lecture', 'vsl', 'ad', 'free'] },
56
65
  theme: { type: 'string', description: 'テーマID' },
57
66
  deck: { type: 'object', description: '{"chapters":[...]}' },
58
67
  },
@@ -61,7 +70,7 @@ const tools = [
61
70
  },
62
71
  {
63
72
  name: 'ai_edit_slide_deck',
64
- description: '既存のスライドデッキを自然言語の指示でAIが修正します(例:「3枚目をもっと具体的に」「料金比較の表スライドを追加」)。slide_index 指定でその1枚だけを対象にできます(速い・確実)。部分的な修正はこのツールを優先。',
73
+ description: '既存のスライドデッキを自然言語の指示でAIが修正します(例:「3枚目をもっと具体的に」「全スライドにナレーション原稿(note)を付けて」「5枚目のナレーションを柔らかく」)。slide_index 指定でその1枚だけを対象にできます(速い・確実)。部分的な修正はこのツールを優先。',
65
74
  annotations: { destructiveHint: false },
66
75
  inputSchema: {
67
76
  type: 'object',
@@ -82,7 +91,7 @@ const tools = [
82
91
  properties: {
83
92
  id: { type: 'string', description: 'デッキID' },
84
93
  title: { type: 'string' },
85
- purpose: { type: 'string', enum: ['document', 'lecture', 'vsl', 'ad'] },
94
+ purpose: { type: 'string', enum: ['document', 'lecture', 'vsl', 'ad', 'free'] },
86
95
  theme: { type: 'string' },
87
96
  deck: { type: 'object', description: '{"chapters":[...]}(省略時は変更なし)' },
88
97
  },
@@ -91,10 +100,63 @@ const tools = [
91
100
  },
92
101
  {
93
102
  name: 'delete_slide_deck',
94
- description: 'スライドデッキを完全に削除します(元に戻せません)。ユーザーの明示的な依頼があるときのみ使用。',
103
+ description: 'スライドデッキをゴミ箱に移動します(restore_slide_deck やUIのゴミ箱からいつでも復元可能)。ユーザーの明示的な依頼があるときのみ使用。完全削除はUIのゴミ箱からのみ。',
95
104
  annotations: { destructiveHint: true },
96
105
  inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'デッキID' } }, required: ['id'] },
97
106
  },
107
+ {
108
+ name: 'restore_slide_deck',
109
+ description: 'ゴミ箱に入れたスライドデッキを復元します(delete_slide_deck の取り消し)。',
110
+ annotations: { destructiveHint: false },
111
+ inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'デッキID' } }, required: ['id'] },
112
+ },
113
+ {
114
+ name: 'archive_slide_deck',
115
+ description: 'スライドデッキをアーカイブ(一覧から退避)/ archived=false で解除します。使わなくなったが残しておきたいスライドの整理に。',
116
+ annotations: { destructiveHint: false },
117
+ inputSchema: { type: 'object', properties: {
118
+ id: { type: 'string', description: 'デッキID' },
119
+ archived: { type: 'boolean', description: 'true=アーカイブ(既定)/ false=解除' },
120
+ }, required: ['id'] },
121
+ },
122
+ {
123
+ name: 'list_slide_folders',
124
+ description: 'スライドのカテゴリ一覧を取得します(一覧画面左サイドバーの分類)。振り分けは set_slide_deck_folder。',
125
+ annotations: { readOnlyHint: true },
126
+ inputSchema: { type: 'object', properties: {}, required: [] },
127
+ },
128
+ {
129
+ name: 'create_slide_folder',
130
+ description: 'スライドのカテゴリを新規作成します(例:「営業資料」「セミナー」)。',
131
+ annotations: { destructiveHint: false },
132
+ inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'カテゴリ名' } }, required: ['name'] },
133
+ },
134
+ {
135
+ name: 'set_slide_deck_folder',
136
+ description: 'スライドデッキをカテゴリに振り分けます。folder_id 省略で未分類に戻します。カテゴリIDは list_slide_folders で確認。',
137
+ annotations: { destructiveHint: false },
138
+ inputSchema: { type: 'object', properties: {
139
+ id: { type: 'string', description: 'デッキID' },
140
+ folder_id: { type: 'string', description: 'カテゴリID(省略=未分類へ)' },
141
+ }, required: ['id'] },
142
+ },
143
+ {
144
+ name: 'share_slide_deck',
145
+ description: `スライドの共有・配布設定を確認/変更し、共有URLを取得します。⚠️外部公開に関わるため、ユーザーが明示的に共有/配布を依頼したときのみ設定を変更すること(設定引数なし=現在の設定とURLの確認のみ)。
146
+ - share_enabled: URLを知っている人に閲覧公開 / share_allow_edit: 編集用URLも有効化 / share_allow_download: PPTX/PNGのDL許可
147
+ - share_password: 閲覧パスワード(remove_password=true で解除) / dist_enabled: 配布URL(別アカウントが自分のアカウントに複製取込)`,
148
+ annotations: { destructiveHint: false },
149
+ inputSchema: { type: 'object', properties: {
150
+ id: { type: 'string', description: 'デッキID' },
151
+ share_enabled: { type: 'boolean' },
152
+ share_allow_edit: { type: 'boolean' },
153
+ share_allow_download: { type: 'boolean' },
154
+ share_password: { type: 'string' },
155
+ remove_password: { type: 'boolean' },
156
+ dist_enabled: { type: 'boolean' },
157
+ share_include_notes: { type: 'boolean', description: 'ノート(ナレーション原稿)も閲覧共有に含める(既定OFF。編集許可ONは常に含む)' },
158
+ }, required: ['id'] },
159
+ },
98
160
  ];
99
161
 
100
162
  const handlers = {
@@ -103,16 +165,18 @@ const handlers = {
103
165
  const kinds = Object.entries(d.kinds || {}).map(([k, v]) => `- ${k}(${v.label}): ${v.spec}`).join('\n');
104
166
  const themes = Object.entries(d.themes || {}).map(([k, v]) => `- ${k}: ${v}`).join('\n');
105
167
  const purposes = Object.entries(d.purposes || {}).map(([k, v]) => `- ${k}: ${v}`).join('\n');
106
- return `## テンプレート(kind)\n${kinds}\n\n## テーマ\n${themes}\n\n## 用途\n${purposes}`;
168
+ const formats = Object.entries(d.formats || {}).map(([k, v]) => `- ${k}: ${v}`).join('\n');
169
+ return `## テンプレート(kind)\n${kinds}\n\n## テーマ\n${themes}\n\n## 用途\n${purposes}\n\n## スライド比率(format)\n${formats}`;
107
170
  },
108
- list_slide_decks: async () => {
109
- const rows = await callApi('/slides');
110
- if (!rows.length) return 'スライドデッキはまだありません。generate_slide_deck で作成できます。';
111
- return rows.map(r => `- ${r.title || '無題'}(${r.slide_count}枚 / ${r.theme} / ${r.purpose})\n ID: ${r.id} / 更新: ${r.updated_at}`).join('\n');
171
+ list_slide_decks: async ({ archived } = {}) => {
172
+ const rows = await callApi(`/slides${archived ? '?archived=1' : ''}`);
173
+ if (!rows.length) return archived ? 'アーカイブ済みのスライドはありません。' : 'スライドデッキはまだありません。generate_slide_deck で作成できます。';
174
+ return rows.map(r => `- ${r.title || '無題'}(${r.slide_count}枚 / ${r.theme} / ${r.purpose}${r.folder_name ? ` / 🏷${r.folder_name}` : ''})\n ID: ${r.id} / 更新: ${r.updated_at}`).join('\n');
112
175
  },
113
- get_slide_deck: async ({ id }) => {
176
+ get_slide_deck: async ({ id, with_narration }) => {
114
177
  const r = await callApi(`/slides/${id}`);
115
- return JSON.stringify({ id: r.id, title: r.title, purpose: r.purpose, theme: r.theme, deck: r.deck }, null, 2);
178
+ const text = with_narration ? (r.text_with_narration || r.text) : r.text;
179
+ return JSON.stringify({ id: r.id, title: r.title, purpose: r.purpose, theme: r.theme, text, deck: r.deck }, null, 2);
116
180
  },
117
181
  generate_slide_deck: async (args) => {
118
182
  const d = await callApi('/slides/generate', { method: 'POST', body: JSON.stringify(args) });
@@ -134,6 +198,41 @@ const handlers = {
134
198
  const d = await callApi(`/slides/${id}`, { method: 'DELETE' });
135
199
  return `✅ ${d.message}`;
136
200
  },
201
+ restore_slide_deck: async ({ id }) => {
202
+ const d = await callApi(`/slides/${id}/restore`, { method: 'POST' });
203
+ return `✅ ${d.message}(${d.title || id})`;
204
+ },
205
+ archive_slide_deck: async ({ id, archived }) => {
206
+ const d = await callApi(`/slides/${id}/archive`, { method: 'POST', body: JSON.stringify({ archived: archived !== false }) });
207
+ return `✅ ${d.message}(${d.title || id})`;
208
+ },
209
+ list_slide_folders: async () => {
210
+ const rows = await callApi('/slides/folders');
211
+ if (!rows.length) return 'カテゴリはまだありません。create_slide_folder で作成できます。';
212
+ return rows.map(f => `- ${f.name}\n ID: ${f.id}`).join('\n');
213
+ },
214
+ create_slide_folder: async ({ name }) => {
215
+ const d = await callApi('/slides/folders', { method: 'POST', body: JSON.stringify({ name }) });
216
+ return `✅ ${d.message}\nID: ${d.id} / 名前: ${d.name}`;
217
+ },
218
+ set_slide_deck_folder: async ({ id, folder_id }) => {
219
+ const d = await callApi(`/slides/${id}/folder`, { method: 'PUT', body: JSON.stringify({ folder_id: folder_id || null }) });
220
+ return `✅ ${d.message}`;
221
+ },
222
+ share_slide_deck: async ({ id, ...rest }) => {
223
+ const hasChange = Object.keys(rest).length > 0;
224
+ const d = hasChange
225
+ ? await callApi(`/slides/${id}/share`, { method: 'PUT', body: JSON.stringify(rest) })
226
+ : await callApi(`/slides/${id}/share`);
227
+ const lines = [
228
+ hasChange ? '✅ 共有設定を更新しました' : '現在の共有設定:',
229
+ `- URL公開: ${d.share_enabled ? 'ON' : 'OFF'} / 編集許可: ${d.share_allow_edit ? 'ON' : 'OFF'} / DL許可: ${d.share_allow_download ? 'ON' : 'OFF'} / パスワード: ${d.has_share_password ? 'あり' : 'なし'} / 配布URL: ${d.dist_enabled ? 'ON' : 'OFF'}`,
230
+ ];
231
+ if (d.share_url) lines.push(`- 共有URL(閲覧): ${d.share_url}`);
232
+ if (d.share_edit_url) lines.push(`- 編集用URL: ${d.share_edit_url}`);
233
+ if (d.dist_url) lines.push(`- 配布URL(別アカウントへ複製取込): ${d.dist_url}`);
234
+ return lines.join('\n');
235
+ },
137
236
  };
138
237
 
139
238
  module.exports = { tools, handlers };
@@ -0,0 +1,104 @@
1
+ // 動画編集ドメイン(docs/VIDEO_PLAN.md Phase 2・v1.71.0〜)
2
+ // スライドデッキから「要素の段階出現・切替アニメ付き」のスライド動画タイムラインを組む機能。
3
+ // 大原則: サーバーが持つのはタイムラインJSONのみ。音声/動画の実データ・mp4書き出しはユーザーPC側(編集画面 /video/<ID>)。
4
+ // → Claude Code / Desktop は手元の音声の文字起こし・SRT・台本を自分で読み、発話タイミングに合わせて
5
+ // timeline を組める(これがMCP連携の本命ユースケース)。
6
+ // ※ プランopt-inの機能(未解放プランでは403)。
7
+ const { callApi } = require('../lib/api');
8
+
9
+ const tools = [
10
+ {
11
+ name: 'get_video_timeline_spec',
12
+ description: '動画タイムライン(timeline JSON)の仕様を取得します。クリップ形式・transition/animの語彙・reveals(要素の段階出現)の組み方・音声同期のコツ。update_video_project で timeline を編集する前に一度確認してください。',
13
+ annotations: { readOnlyHint: true },
14
+ inputSchema: { type: 'object', properties: {}, required: [] },
15
+ },
16
+ {
17
+ name: 'list_video_projects',
18
+ description: '動画プロジェクトの一覧(ID・タイトル・元スライドデッキ名・更新日時)を取得します。',
19
+ annotations: { readOnlyHint: true },
20
+ inputSchema: { type: 'object', properties: {}, required: [] },
21
+ },
22
+ {
23
+ name: 'get_video_project',
24
+ description: '動画プロジェクトの内容を取得します。timeline=タイムラインJSON・slides=参照デッキの各スライド情報(title・note=ナレーション原稿・reveal_paths=段階出現できる要素の一覧(path と人間向けラベル))。タイムラインを編集するときは reveal_paths の path をそのまま reveals に使ってください。',
25
+ annotations: { readOnlyHint: true },
26
+ inputSchema: { type: 'object', properties: {
27
+ id: { type: 'string', description: 'プロジェクトID(list_video_projectsで確認)' },
28
+ }, required: ['id'] },
29
+ },
30
+ {
31
+ name: 'create_video_project',
32
+ description: `スライドデッキから動画プロジェクトを新規作成します。deck_id を渡すと、各スライドの note(ナレーション原稿)の分量比でスライド尺を自動配分し、要素の段階出現(フェード)も等間隔で自動設定した初期タイムラインを作ります。
33
+ 作成後の流れ: ①このツール ②必要なら update_video_project で発話タイミングに合わせて微調整 ③ユーザーが編集画面(/video/<ID>)で音声ファイルを選択し、プレビュー確認して mp4 書き出し(すべてPC内処理)。
34
+ 手元に音声の文字起こし(タイムスタンプ付き)がある場合は、total_seconds に音声の長さを渡し、その後 update_video_project で各クリップの duration / reveals.at を発話に合わせると音声同期動画になります。`,
35
+ annotations: { destructiveHint: false },
36
+ inputSchema: { type: 'object', properties: {
37
+ deck_id: { type: 'string', description: '元スライドデッキID(list_slide_decksで確認)' },
38
+ title: { type: 'string', description: '動画タイトル(省略時はデッキ名から自動)' },
39
+ total_seconds: { type: 'number', description: '動画の総尺(秒)。音声の長さが分かっていれば渡す(省略時は枚数×8秒)' },
40
+ }, required: ['deck_id'] },
41
+ },
42
+ {
43
+ name: 'update_video_project',
44
+ description: '動画プロジェクトを更新します(title / timeline)。timeline は get_video_timeline_spec の形式で全置換。既存の timeline は get_video_project で取得し、必要箇所だけ変えて渡してください(クリップの start は隙間なく連続させること)。音声実データはPC側のため、audio トラックは既存の内容を維持して渡すこと。',
45
+ annotations: { destructiveHint: false },
46
+ inputSchema: { type: 'object', properties: {
47
+ id: { type: 'string', description: 'プロジェクトID' },
48
+ title: { type: 'string' },
49
+ timeline: { type: 'object', description: 'タイムラインJSON(全置換・形式は get_video_timeline_spec)' },
50
+ }, required: ['id'] },
51
+ },
52
+ {
53
+ name: 'auto_build_video_timeline',
54
+ description: 'タイムラインを自動で組み直します(参照デッキの note 分量比で尺配分+要素出現を等間隔設定)。総尺を変えたいとき・手動編集をやり直したいときに。音声トラックは維持されます。',
55
+ annotations: { destructiveHint: true },
56
+ inputSchema: { type: 'object', properties: {
57
+ id: { type: 'string', description: 'プロジェクトID' },
58
+ total_seconds: { type: 'number', description: '動画の総尺(秒・省略時は枚数×8秒)' },
59
+ with_reveals: { type: 'boolean', description: 'false=要素の段階出現を付けない(省略=付ける)' },
60
+ }, required: ['id'] },
61
+ },
62
+ {
63
+ name: 'delete_video_project',
64
+ description: '動画プロジェクトを削除します(タイムライン定義のみ削除・元スライドや手元の音声ファイルは消えません)。',
65
+ annotations: { destructiveHint: true },
66
+ inputSchema: { type: 'object', properties: {
67
+ id: { type: 'string', description: 'プロジェクトID' },
68
+ }, required: ['id'] },
69
+ },
70
+ ];
71
+
72
+ const handlers = {
73
+ get_video_timeline_spec: async () => {
74
+ const d = await callApi('/video/schema');
75
+ return d.spec;
76
+ },
77
+ list_video_projects: async () => {
78
+ const rows = await callApi('/video');
79
+ if (!rows.length) return '動画プロジェクトはまだありません。create_video_project で作成できます。';
80
+ return rows.map(r => `- ${r.title || '無題'}${r.deck_title ? `(元: ${r.deck_title})` : ''}\n ID: ${r.id} / 更新: ${r.updated_at}`).join('\n');
81
+ },
82
+ get_video_project: async ({ id }) => {
83
+ const r = await callApi(`/video/${id}`);
84
+ return JSON.stringify(r, null, 2);
85
+ },
86
+ create_video_project: async (args) => {
87
+ const d = await callApi('/video', { method: 'POST', body: JSON.stringify(args) });
88
+ return `✅ ${d.message}\nID: ${d.id}\nタイトル: ${d.title}\n編集画面: ${d.edit_url}\n(音声ファイルの選択・プレビュー・mp4書き出しはユーザーが編集画面で行います)`;
89
+ },
90
+ update_video_project: async ({ id, ...rest }) => {
91
+ const d = await callApi(`/video/${id}`, { method: 'PATCH', body: JSON.stringify(rest) });
92
+ return `✅ ${d.message}\nID: ${d.id}`;
93
+ },
94
+ auto_build_video_timeline: async ({ id, ...rest }) => {
95
+ const d = await callApi(`/video/${id}/auto-build`, { method: 'POST', body: JSON.stringify(rest) });
96
+ return `✅ ${d.message}`;
97
+ },
98
+ delete_video_project: async ({ id }) => {
99
+ const d = await callApi(`/video/${id}`, { method: 'DELETE' });
100
+ return `✅ ${d.message}`;
101
+ },
102
+ };
103
+
104
+ module.exports = { tools, handlers };
package/index.js CHANGED
@@ -21,12 +21,13 @@ const brain = require('./domains/brain');
21
21
  const funnels = require('./domains/funnels');
22
22
  const skills = require('./domains/skills');
23
23
  const slides = require('./domains/slides');
24
+ const video = require('./domains/video');
24
25
  const analytics = require('./domains/analytics');
25
26
  const myasp = require('./domains/myasp');
26
27
  const wordpress = require('./domains/wordpress');
27
28
  const macbuil = require('./domains/macbuil');
28
29
 
29
- const allDomains = [knowledge, agentPresets, workflows, chatbots, schedulesAndTasks, projects, brain, funnels, skills, slides, analytics, myasp, wordpress, macbuil];
30
+ const allDomains = [knowledge, agentPresets, workflows, chatbots, schedulesAndTasks, projects, brain, funnels, skills, slides, video, analytics, myasp, wordpress, macbuil];
30
31
 
31
32
  const TOOLS = allDomains.flatMap(d => d.tools);
32
33
  const HANDLERS = Object.assign({}, ...allDomains.map(d => d.handlers));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "owner-clone-ai-mcp",
3
- "version": "1.69.0",
3
+ "version": "1.71.0",
4
4
  "description": "MCP server for Owner Clone AI — exposes knowledge and agent presets to Claude Code",
5
5
  "main": "index.js",
6
6
  "bin": {