owner-clone-ai-mcp 1.29.2 → 1.31.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/knowledge.js +47 -7
- package/domains/schedulesAndTasks.js +19 -9
- package/index.js +4 -0
- package/lib/api.js +5 -1
- package/package.json +1 -1
package/domains/knowledge.js
CHANGED
|
@@ -43,6 +43,16 @@ const tools = [
|
|
|
43
43
|
required: ['id'],
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
|
+
{
|
|
47
|
+
name: 'get_knowledge_image',
|
|
48
|
+
description: '画像カテゴリ(image)のナレッジの画像そのものを取得して内容を視覚的に確認します。画像に何が写っているか・見た目を判断する必要があるときに使います。',
|
|
49
|
+
annotations: { readOnlyHint: true },
|
|
50
|
+
inputSchema: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: { id: { type: 'string', description: '画像ナレッジのID' } },
|
|
53
|
+
required: ['id'],
|
|
54
|
+
},
|
|
55
|
+
},
|
|
46
56
|
{
|
|
47
57
|
name: 'list_knowledge_folders',
|
|
48
58
|
description: 'ナレッジのフォルダ一覧を取得します。',
|
|
@@ -51,27 +61,42 @@ const tools = [
|
|
|
51
61
|
},
|
|
52
62
|
{
|
|
53
63
|
name: 'create_knowledge',
|
|
54
|
-
description:
|
|
64
|
+
description: `Owner Clone AIにナレッジを新規作成します。【書き込み権限付きキーが必要】作成後、自動的にベクトル化されセマンティック検索に対応します。
|
|
65
|
+
|
|
66
|
+
text_content(自由テキスト)か、content(カテゴリ別の構造化オブジェクト)のどちらかを渡してください。
|
|
67
|
+
content を渡すと各入力項目が正しく構造化保存され、本文テキストは自動生成されます(UIフォームと同じ扱い)。
|
|
68
|
+
|
|
69
|
+
■ content のカテゴリ別フィールド(カテゴリに合わせて設定):
|
|
70
|
+
persona: persona_name(お名前) / age_gender(年齢) / gender(性別:男性|女性|その他) / job / concerns(緊急性のある悩みTOP3) / level(初級者|中級者|上級者) / level_reason / special_words / past_failures / wants(具体的ゴール) / info_source / purchase_behavior / why_instant_sell
|
|
71
|
+
profile: company_name / founded(設立年・事業開始年) / business / achievements / media / expertise(専門性) / representative
|
|
72
|
+
testimonial: publish_consent(掲載可否:全て掲載可|名前を伏せて掲載可|掲載不可) / service_name / customer_name / industry / self_intro / before_reason / results / how_achieved / beyond_expect / surrounding / recommend_for
|
|
73
|
+
tone: base_style / expressions / avoid / length_style / layout("mobile"=スマホ対応|"pc"=PC最適化) / sample
|
|
74
|
+
product: product_name / category(商品ジャンル) / price / urgent_problems / why_created / for_whom / services(★配列)
|
|
75
|
+
offer: offer_name / offer_type(メルマガ・公式LINEの登録誘導|資料・サンプル請求|個別相談・セミナー開催|チャレンジ企画|ウェビナー|その他) / price / duration / urgent_problems / why_created / for_whom / bonuses / guarantee / services(★配列) / objections / cta
|
|
76
|
+
other / note_manual / note_research / note_hint / note_article / note_meeting: body
|
|
77
|
+
■ product/offer の services(繰り返し複合・オブジェクト配列):
|
|
78
|
+
services: [{ name:"サービス名", value:"いくらの価値があるか", result_1m:"1ヶ月で見込める結果", result_3m:"3ヶ月で見込める結果", result_6m:"6ヶ月で見込める結果", advantages:"競合より優れている3つの理由" }, ...複数可]`,
|
|
55
79
|
annotations: { destructiveHint: false, idempotentHint: false },
|
|
56
80
|
inputSchema: {
|
|
57
81
|
type: 'object',
|
|
58
82
|
properties: {
|
|
59
83
|
title: { type: 'string', description: 'ナレッジのタイトル' },
|
|
60
|
-
text_content: { type: 'string', description: '
|
|
84
|
+
text_content: { type: 'string', description: 'ナレッジの本文テキスト(content を渡す場合は不要)' },
|
|
85
|
+
content: { type: 'object', description: 'カテゴリ別の構造化オブジェクト(上記参照)。渡すと本文テキストは自動生成される。product/offer の services は配列' },
|
|
61
86
|
category: {
|
|
62
87
|
type: 'string',
|
|
63
|
-
description: '
|
|
64
|
-
enum: ['product', 'profile', 'testimonial', 'persona', 'tone', 'other'],
|
|
88
|
+
description: 'カテゴリ',
|
|
89
|
+
enum: ['offer', 'product', 'profile', 'testimonial', 'persona', 'tone', 'other', 'note_manual', 'note_research', 'note_hint', 'note_article', 'note_meeting'],
|
|
65
90
|
},
|
|
66
91
|
folder_id: { type: 'string', description: 'フォルダID(省略可)' },
|
|
67
92
|
tags: { type: 'array', items: { type: 'string' }, description: 'タグの配列(例: ["マーケティング", "集客"])省略可。省略時はタグなしで登録。' },
|
|
68
93
|
},
|
|
69
|
-
required: ['title'
|
|
94
|
+
required: ['title'],
|
|
70
95
|
},
|
|
71
96
|
},
|
|
72
97
|
{
|
|
73
98
|
name: 'update_knowledge',
|
|
74
|
-
description: '既存のナレッジを更新します。【書き込み権限付きキーが必要】本文を変更した場合は自動的に再ベクトル化されます。folder_id でフォルダ移動も可能(null で未分類に移動)。',
|
|
99
|
+
description: '既存のナレッジを更新します。【書き込み権限付きキーが必要】本文を変更した場合は自動的に再ベクトル化されます。folder_id でフォルダ移動も可能(null で未分類に移動)。content(カテゴリ別構造化オブジェクト)を渡すと構造化保存+本文自動生成(フィールド仕様は create_knowledge 参照)。',
|
|
75
100
|
annotations: { destructiveHint: false, idempotentHint: true },
|
|
76
101
|
inputSchema: {
|
|
77
102
|
type: 'object',
|
|
@@ -79,6 +104,7 @@ const tools = [
|
|
|
79
104
|
id: { type: 'string', description: '更新するナレッジのID' },
|
|
80
105
|
title: { type: 'string', description: '新しいタイトル(省略時は変更なし)' },
|
|
81
106
|
text_content: { type: 'string', description: '新しい本文(省略時は変更なし)' },
|
|
107
|
+
content: { type: 'object', description: 'カテゴリ別の構造化オブジェクト(create_knowledge参照)。渡すと本文を自動再生成。product/offer の services は配列' },
|
|
82
108
|
category: { type: 'string', description: '新しいカテゴリ(省略時は変更なし)' },
|
|
83
109
|
folder_id: { type: 'string', description: '移動先フォルダID(null または省略で変更なし、空文字列で未分類へ移動)' },
|
|
84
110
|
tags: { type: 'array', items: { type: 'string' }, description: 'タグの配列(省略時は変更なし、空配列[]でタグを全削除)' },
|
|
@@ -291,7 +317,19 @@ const handlers = {
|
|
|
291
317
|
const data = await callApi(`/knowledge/${args.id}`);
|
|
292
318
|
const tagLine = data.tags?.length ? `\nタグ: ${data.tags.join(', ')}` : '\nタグ: なし';
|
|
293
319
|
const folderLine = data.folder_id ? `\nフォルダID: ${data.folder_id}` : '\nフォルダ: 未分類';
|
|
294
|
-
|
|
320
|
+
const imgHint = data.category === 'image' ? '\n\n※これは画像ナレッジです。画像そのものを見るには get_knowledge_image を使ってください。' : '';
|
|
321
|
+
return `タイトル: ${data.title}\nカテゴリ: ${data.category || 'その他'}${tagLine}${folderLine}\n作成日: ${data.created_at?.slice(0, 10)} / 更新日: ${data.updated_at?.slice(0, 10)}${imgHint}\n\n--- 内容 ---\n${data.text_content}`;
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
// 画像本体を取得して MCP の image コンテンツとして返す(Claude Desktop等でAIが視認できる)
|
|
325
|
+
async get_knowledge_image(args) {
|
|
326
|
+
const data = await callApi(`/knowledge/${args.id}/image`);
|
|
327
|
+
return {
|
|
328
|
+
content: [
|
|
329
|
+
{ type: 'text', text: `画像「${data.title || ''}」` },
|
|
330
|
+
{ type: 'image', data: data.base64, mimeType: data.mimeType || 'image/png' },
|
|
331
|
+
],
|
|
332
|
+
};
|
|
295
333
|
},
|
|
296
334
|
|
|
297
335
|
async list_knowledge_folders(args) {
|
|
@@ -311,6 +349,7 @@ const handlers = {
|
|
|
311
349
|
body: JSON.stringify({
|
|
312
350
|
title: args.title, text_content: args.text_content,
|
|
313
351
|
category: args.category || 'other', folder_id: args.folder_id,
|
|
352
|
+
...(args.content !== undefined ? { content: args.content } : {}),
|
|
314
353
|
...(args.tags !== undefined ? { tags: args.tags } : {}),
|
|
315
354
|
}),
|
|
316
355
|
});
|
|
@@ -322,6 +361,7 @@ const handlers = {
|
|
|
322
361
|
const body = {};
|
|
323
362
|
if (args.title) body.title = args.title;
|
|
324
363
|
if (args.text_content) body.text_content = args.text_content;
|
|
364
|
+
if (args.content !== undefined) body.content = args.content;
|
|
325
365
|
if (args.category) body.category = args.category;
|
|
326
366
|
if (args.folder_id !== undefined) body.folder_id = args.folder_id || null;
|
|
327
367
|
if (args.tags !== undefined) body.tags = args.tags;
|
|
@@ -88,7 +88,7 @@ const tools = [
|
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
name: 'create_task',
|
|
91
|
-
description: 'タスクを新規作成します(type=manual
|
|
91
|
+
description: 'タスクを新規作成します(type=manual)。担当者(assignee)とプロジェクト(project)も指定できます。【書き込み権限付きキーが必要】',
|
|
92
92
|
annotations: { destructiveHint: false, idempotentHint: false },
|
|
93
93
|
inputSchema: {
|
|
94
94
|
type: 'object',
|
|
@@ -97,13 +97,18 @@ const tools = [
|
|
|
97
97
|
body: { type: 'string', description: '詳細・内容(省略可)' },
|
|
98
98
|
priority: { type: 'string', description: '優先度: low/normal/high(デフォルト: normal)' },
|
|
99
99
|
due_date: { type: 'string', description: '期限日時 ISO8601(省略可)' },
|
|
100
|
+
assignee_id: { type: 'string', description: '担当者のメンバーID(list_team_members で取得したUUID)。オーナー自身のID指定も可。' },
|
|
101
|
+
assignee_name: { type: 'string', description: '担当者の名前(部分一致で検索)。assignee_id を指定しない場合に使用。' },
|
|
102
|
+
project_id: { type: 'string', description: 'このタスクを紐づけるプロジェクトのID(list_projects で取得したUUID)' },
|
|
103
|
+
notify_assignee: { type: 'boolean', description: '担当者にChatworkで通知するか(デフォルト: false。trueで通知)' },
|
|
104
|
+
notify_chatwork_setting_id: { type: 'string', description: '担当者通知の送信先ChatworkグループID(list_chatwork_settings で取得。未指定時は自動選択)' },
|
|
100
105
|
},
|
|
101
106
|
required: ['title'],
|
|
102
107
|
},
|
|
103
108
|
},
|
|
104
109
|
{
|
|
105
110
|
name: 'update_task',
|
|
106
|
-
description: '
|
|
111
|
+
description: 'タスクを更新します。担当者(assignee)・プロジェクト(project)も変更できます。【書き込み権限付きキーが必要】manual タスクは全フィールド更新可。他タイプはステータス変更のみ可。',
|
|
107
112
|
annotations: { destructiveHint: false, idempotentHint: true },
|
|
108
113
|
inputSchema: {
|
|
109
114
|
type: 'object',
|
|
@@ -114,6 +119,9 @@ const tools = [
|
|
|
114
119
|
priority: { type: 'string', description: '新しい優先度: low/normal/high(manual のみ)' },
|
|
115
120
|
due_date: { type: 'string', description: '新しい期限(manual のみ、null で期限解除)' },
|
|
116
121
|
status: { type: 'string', description: 'ステータス変更: pending/done/dismissed' },
|
|
122
|
+
assignee_id: { type: 'string', description: '担当者のメンバーID(list_team_members のUUID。空文字で担当者解除)' },
|
|
123
|
+
assignee_name: { type: 'string', description: '担当者の名前(部分一致)。"解除"で担当者を外す。' },
|
|
124
|
+
project_id: { type: 'string', description: '紐づけるプロジェクトのID(list_projects のUUID。空文字で解除)' },
|
|
117
125
|
},
|
|
118
126
|
required: ['id'],
|
|
119
127
|
},
|
|
@@ -207,18 +215,20 @@ const handlers = {
|
|
|
207
215
|
},
|
|
208
216
|
|
|
209
217
|
async create_task(args) {
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
});
|
|
218
|
+
const body = {};
|
|
219
|
+
['title','body','priority','due_date','assignee_id','assignee_name','project_id','notify_assignee','notify_chatwork_setting_id']
|
|
220
|
+
.forEach(f => { if (args[f] !== undefined) body[f] = args[f]; });
|
|
221
|
+
const data = await callApi('/tasks', { method: 'POST', body: JSON.stringify(body) });
|
|
214
222
|
return `✅ ${data.message}\nID: ${data.id}\nタイトル: ${data.title}\n優先度: ${data.priority}` +
|
|
215
|
-
(data.due_date ? `\n期限: ${data.due_date.slice(0, 10)}` : '')
|
|
223
|
+
(data.due_date ? `\n期限: ${data.due_date.slice(0, 10)}` : '') +
|
|
224
|
+
(data.assignee_id ? `\n担当者ID: ${data.assignee_id}` : '') +
|
|
225
|
+
(data.project_id ? `\nプロジェクトID: ${data.project_id}` : '');
|
|
216
226
|
},
|
|
217
227
|
|
|
218
228
|
async update_task(args) {
|
|
219
229
|
const body = {};
|
|
220
|
-
|
|
221
|
-
|
|
230
|
+
['title','body','priority','due_date','status','assignee_id','assignee_name','project_id']
|
|
231
|
+
.forEach(f => { if (args[f] !== undefined) body[f] = args[f]; });
|
|
222
232
|
const data = await callApi(`/tasks/${args.id}`, { method: 'PATCH', body: JSON.stringify(body) });
|
|
223
233
|
return `✅ ${data.message}\nID: ${data.id}`;
|
|
224
234
|
},
|
package/index.js
CHANGED
|
@@ -45,6 +45,10 @@ async function main() {
|
|
|
45
45
|
const { name, arguments: args } = request.params;
|
|
46
46
|
try {
|
|
47
47
|
const result = await executeTool(name, args || {});
|
|
48
|
+
// ハンドラが MCP コンテンツ(画像など)を直接返した場合はそのまま返す
|
|
49
|
+
if (result && typeof result === 'object' && Array.isArray(result.content)) {
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
48
52
|
return { content: [{ type: 'text', text: result }] };
|
|
49
53
|
} catch (err) {
|
|
50
54
|
return {
|
package/lib/api.js
CHANGED
|
@@ -14,7 +14,11 @@ async function callApi(path, options = {}) {
|
|
|
14
14
|
},
|
|
15
15
|
});
|
|
16
16
|
const json = await res.json();
|
|
17
|
-
if (!res.ok)
|
|
17
|
+
if (!res.ok) {
|
|
18
|
+
// バックエンドが detail(DB例外メッセージ等)を返す場合は原因特定のため併記
|
|
19
|
+
const msg = json && json.detail ? `${json.error || 'エラー'}: ${json.detail}` : (json.error || `API error ${res.status}`);
|
|
20
|
+
throw new Error(msg);
|
|
21
|
+
}
|
|
18
22
|
return json;
|
|
19
23
|
}
|
|
20
24
|
|