owner-clone-ai-mcp 1.77.0 → 1.77.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/domains/slides.js CHANGED
@@ -213,12 +213,34 @@ const handlers = {
213
213
  return `- ${b.name}(テーマ:${b.theme || '未指定'}${parts ? ' / ' + parts : ''})\n 更新: ${b.updated_at}`;
214
214
  }).join('\n');
215
215
  },
216
+ // ⚠️ 2026-09-30: この2つは `callApi(path, 'POST', body)` という別流儀で書かれており、
217
+ // 文字列が options として展開されて {0:'P',1:'O',2:'S',3:'T'} になり、
218
+ // method も body も付かず **GET が飛んでいた**(153箇所中この2箇所だけの誤用)。
219
+ // ・apply は GET のルートが無く 404 のHTMLを res.json() が食って
220
+ // 「Unexpected token '<'」になっていた
221
+ // ・save は GET /slides/brand-themes(一覧)が 200 を返すためエラーにならず、
222
+ // r.name が undefined のまま「保存しました」と**嘘の成功**を返していた(より危険)
223
+ // 正しい形は callApi(path, { method, body })。
216
224
  save_brand_theme: async ({ name, theme, deck }) => {
217
- const r = await callApi('/slides/brand-themes', 'POST', { name, theme, deck: deck || {} });
225
+ const r = await callApi('/slides/brand-themes', {
226
+ method: 'POST',
227
+ body: JSON.stringify({ name, theme, deck: deck || {} }),
228
+ });
229
+ // ⚠️ 応答に name が無いのに成功を名乗らない(サイレント失敗の再発防止)
230
+ if (!r || !r.name) {
231
+ throw new Error('テーマテンプレートの保存結果を確認できませんでした(応答に name がありません)。list_brand_themes で保存されたか確認してください。');
232
+ }
218
233
  return `テーマテンプレート「${r.name}」を保存しました。apply_brand_theme で他のスライドにも当てられます。`;
219
234
  },
220
235
  apply_brand_theme: async ({ name, deck_id }) => {
221
- const r = await callApi(`/slides/brand-themes/${encodeURIComponent(name)}/apply`, 'POST', { deck_id });
236
+ const r = await callApi(`/slides/brand-themes/${encodeURIComponent(name)}/apply`, {
237
+ method: 'POST',
238
+ body: JSON.stringify({ deck_id }),
239
+ });
240
+ // ⚠️ 同上。適用できていないのに「適用しました」と言わない
241
+ if (!r || !r.applied) {
242
+ throw new Error('テーマテンプレートの適用結果を確認できませんでした(応答に applied がありません)。get_slide_deck でデッキの見た目を確認してください。');
243
+ }
222
244
  return `「${r.applied}」の見た目を「${r.deck?.title || deck_id}」に適用しました(本文は変更していません)。`;
223
245
  },
224
246
  get_slide_deck: async ({ id, with_narration }) => {
package/lib/api.js CHANGED
@@ -7,6 +7,18 @@ const API_KEY = process.env.OCR_API_KEY;
7
7
  const BASE_URL = (process.env.OCR_BASE_URL || 'https://api.ownercloneai.com').replace(/\/$/, '');
8
8
 
9
9
  async function callApi(path, options = {}) {
10
+ // ⚠️ 2026-09-30: `callApi(path, 'POST', body)` という別流儀で書かれた2箇所が静かに壊れていた
11
+ // (domains/slides.js の save_brand_theme / apply_brand_theme)。文字列を options として
12
+ // 展開すると {0:'P',1:'O',2:'S',3:'T'} になり method も body も付かず GET が飛ぶ。
13
+ // GET が 200 を返すエンドポイントでは**嘘の成功**になるため、型で弾いて気づけるようにする。
14
+ // ⚠️ 3引数形を受け付ける案は採らない(2つの流儀が併存すると同じ事故が再発する)。
15
+ if (options === null || typeof options !== 'object' || Array.isArray(options)) {
16
+ const got = options === null ? 'null' : (Array.isArray(options) ? 'array' : typeof options);
17
+ throw new Error(
18
+ `callApi の第2引数は fetch のオプションオブジェクトです(受け取った型: ${got})。`
19
+ + `callApi(path, { method: 'POST', body: JSON.stringify(...) }) の形で呼んでください。`
20
+ );
21
+ }
10
22
  const url = `${BASE_URL}/api/mcp/v1${path}`;
11
23
  const res = await fetch(url, {
12
24
  ...options,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "owner-clone-ai-mcp",
3
- "version": "1.77.0",
3
+ "version": "1.77.1",
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": {