owner-clone-ai-mcp 1.77.0 → 1.78.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/skills.js CHANGED
@@ -190,7 +190,7 @@ is_admin_published / allowed_plan_ids はAdmin権限がある場合のみ反映
190
190
  display_name: { type: 'string', description: '表示名(日本語OK)' },
191
191
  description: { type: 'string', description: 'スキルの用途説明' },
192
192
  prompt_template: { type: 'string', description: 'スキル実行時の指示テキスト。prepare_skill(Claude Code自律実行)で使う場合はMCPツール呼び出し指示を含めてよい。invoke_skill(サーバー実行)で使う場合はテキスト処理の指示のみ。' },
193
- parameters: { type: 'array', items: { type: 'object' }, description: 'パラメータ定義リスト。配列全体を置き換えるため、既存パラメータも含めて全て渡すこと [{name, description, required, default_value, input_type, options(input_type=select時の選択肢文字列配列), hidden}]' },
193
+ parameters: { type: 'array', items: { type: 'object' }, description: '⚠️ 配列全体を置き換える。1つ追加・変更するだけの場合も、まず get_skill の「パラメータ定義(生JSON)」をそのままコピーし、そこへ追加・変更して全件渡すこと(整形テキストから書き直すと options / input_type / hidden が失われて選択肢が壊れる)。[{name, description, required, default_value, input_type, options(input_type=select時の選択肢文字列配列), hidden}]' },
194
194
  knowledge_item_ids: { type: 'array', items: { type: 'string' }, description: '参照するナレッジのID一覧(UUID文字列)。配列全体を置き換える' },
195
195
  knowledge_folder_ids: { type: 'array', items: { type: 'string' }, description: '参照するナレッジフォルダID一覧(UUID文字列)。配列全体を置き換える' },
196
196
  preset_id: { type: 'integer', description: 'AIパートナーのID(整数)。null を渡すと解除' },
@@ -488,6 +488,12 @@ const handlers = {
488
488
  const paramStr = params.length
489
489
  ? params.map(p => ` - ${p.name}${p.required ? '(必須)' : '(任意)'}: ${p.description || ''}${p.default_value ? ` [デフォルト: ${p.default_value}]` : ''}`).join('\n')
490
490
  : ' なし';
491
+ // ⚠️ 2026-10-01: 上の整形は name / 必須任意 / description / default_value だけで、
492
+ // options(select の選択肢)・input_type・hidden が落ちていた。
493
+ // update_skill の parameters は **配列全体の置き換え** なので、1つ足すだけでも
494
+ // 取得できない options を推測で書き直すことになり、選択肢が壊れる危険があった。
495
+ // そのまま update_skill に渡せる生JSONを併記する。
496
+ const paramJson = params.length ? JSON.stringify(params, null, 2) : '[]';
491
497
  const isGoal = s.skill_type === 'agent_goal';
492
498
  return [
493
499
  `ID: ${s.id}`,
@@ -504,6 +510,9 @@ const handlers = {
504
510
  `プロンプトテンプレート:\n${s.prompt_template || 'なし'}`,
505
511
  ]),
506
512
  `パラメータ:\n${paramStr}`,
513
+ // ⚠️ update_skill の parameters は配列全体の置き換え。1つ足すときも**このJSONをそのままコピーして
514
+ // 末尾に追加**する。整形テキストから書き直すと options / input_type / hidden が失われる
515
+ `パラメータ定義(生JSON・update_skill にそのまま渡せる):\n${paramJson}`,
507
516
  `ナレッジ指定アイテム数: ${(s.knowledge_item_ids || []).length}件`,
508
517
  `ナレッジ指定フォルダ数: ${(s.knowledge_folder_ids || []).length}件`,
509
518
  `AIパートナー: ${s.preset_name || 'なし'}`,
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/index.js CHANGED
@@ -35,6 +35,8 @@ const HANDLERS = Object.assign({}, ...allDomains.map(d => d.handlers));
35
35
  // adminOnly ツール(標準AIパートナー操作など)は、接続キーがAdminの時だけ tools/list に出す。
36
36
  // 取得失敗時は安全側で「非Admin扱い=隠す」。ツール返却時は非標準フィールド adminOnly を除去。
37
37
  const { callApi } = require('./lib/api');
38
+ // 配布物の版数(serverInfo で返す)。ハードコードするとずれるので package.json から読む
39
+ const PKG_VERSION = require('./package.json').version;
38
40
  let _isAdminCache = null;
39
41
  async function keyIsAdmin() {
40
42
  if (_isAdminCache !== null) return _isAdminCache;
@@ -53,7 +55,12 @@ async function executeTool(name, args) {
53
55
  // ── MCPサーバー起動 ────────────────────────────────────────────
54
56
  async function main() {
55
57
  const server = new Server(
56
- { name: 'owner-clone-ai', version: '1.11.0' },
58
+ // ⚠️ 2026-10-01: ここが '1.11.0' で固定されており、package.json(実際の版)と
59
+ // ずれていた。MCPのハンドシェイクで返る版が実物と違うと、
60
+ // 「どの版が動いているか」を利用者側から確認できず、版数トラブルの切り分けができない
61
+ // (1.77.1 の公開直後にCDN伝播待ちで 404 になった件で実際に困った)。
62
+ // package.json から読むことで、以後ずれない。
63
+ { name: 'owner-clone-ai', version: PKG_VERSION },
57
64
  { capabilities: { tools: {} } }
58
65
  );
59
66
 
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.78.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": {