owner-clone-ai-mcp 1.75.0 → 1.77.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.
@@ -83,7 +83,12 @@ const handlers = {
83
83
  const lines = data.projects.map(p =>
84
84
  `- [${p.id}] ${p.name} [${p.status}]` +
85
85
  (p.due_date ? ` 期限:${p.due_date.slice(0, 10)}` : '') +
86
- ` タスク:${p.task_count ?? 0}件` +
86
+ // ⚠️ APIが返すキーは total_tasks / done_tasks / pending_tasks。
87
+ // 以前は存在しない p.task_count を読んでいたため **常に「タスク:0件」** になっていた。
88
+ // COUNT() は bigint=文字列で返るので Number() で数値化する。
89
+ ` タスク:${Number(p.total_tasks || 0)}件` +
90
+ (Number(p.total_tasks || 0) > 0
91
+ ? `(完了${Number(p.done_tasks || 0)}/未対応${Number(p.pending_tasks || 0)})` : '') +
87
92
  (p.approval_notify_setting_id ? ` Chatwork通知:あり` : '') +
88
93
  (p.description ? `\n ${p.description}` : '')
89
94
  );
@@ -63,9 +63,20 @@ const tools = [
63
63
  required: ['id'],
64
64
  },
65
65
  },
66
+ {
67
+ name: 'list_team_members',
68
+ description: `チームメンバー(タスクの担当者に指定できる人)の一覧を取得します。
69
+ assignee_id を調べるために使います。先頭はオーナー自身(role: owner)です。
70
+ ※ 通常は assignee_name に名前を渡せば自動で解決されるため、このツールは
71
+ 同姓の人が複数いる等でIDを確定したいときに使います。`,
72
+ annotations: { readOnlyHint: true },
73
+ inputSchema: { type: 'object', properties: {} },
74
+ },
66
75
  {
67
76
  name: 'list_tasks',
68
- description: 'タスク一覧を取得します。ステータスやタイプで絞り込み可能。',
77
+ description: `タスク一覧を取得します。ステータス・タイプ・担当者で絞り込めます(複数指定はAND条件)。
78
+ 「田中さんの未完了タスク」のような問いには status:"pending" と assignee_name:"田中" を併せて指定します。
79
+ 各行の末尾に担当者名が付きます(未設定は表示なし)。`,
69
80
  annotations: { readOnlyHint: true },
70
81
  inputSchema: {
71
82
  type: 'object',
@@ -73,12 +84,15 @@ const tools = [
73
84
  status: { type: 'string', description: 'ステータス絞り込み: pending/done/dismissed/approved/rejected(省略時: 全件)' },
74
85
  type: { type: 'string', description: 'タイプ絞り込み: manual/workflow_approval/workflow_review(省略時: 全件)' },
75
86
  limit: { type: 'number', description: '取得件数(デフォルト: 50、最大: 200)' },
87
+ assignee_name: { type: 'string', description: '担当者名で絞り込み(部分一致。姓だけでも可)。オーナー自身の名前も可。"自分" でAPIキーの持ち主(オーナー)。該当者が居なければエラーではなく0件。複数該当するときは全員分を返す' },
88
+ assignee_id: { type: 'string', description: '担当者IDで絞り込み(list_team_members のUUID。オーナー自身のIDも可)。assignee_name より優先' },
89
+ unassigned: { type: 'boolean', description: 'true で「担当者が未設定のタスク」だけに絞る。assignee_name に "未割当"/"未設定"/"なし" を渡しても同じ' },
76
90
  },
77
91
  },
78
92
  },
79
93
  {
80
94
  name: 'get_task',
81
- description: '指定したタスクの詳細を取得します。',
95
+ description: '指定したタスクの詳細を取得します。担当者名も返します(未設定なら「なし」)。',
82
96
  annotations: { readOnlyHint: true },
83
97
  inputSchema: {
84
98
  type: 'object',
@@ -98,7 +112,7 @@ const tools = [
98
112
  priority: { type: 'string', description: '優先度: low/normal/high(デフォルト: normal)' },
99
113
  due_date: { type: 'string', description: '期限日時 ISO8601(省略可)' },
100
114
  assignee_id: { type: 'string', description: '担当者のメンバーID(list_team_members で取得したUUID)。オーナー自身のID指定も可。' },
101
- assignee_name: { type: 'string', description: '担当者の名前(部分一致で検索)。assignee_id を指定しない場合に使用。' },
115
+ assignee_name: { type: 'string', description: '担当者の名前(部分一致で検索)。assignee_id を指定しない場合に使用。オーナー(APIキーの持ち主)も名前で指定できる。"自分" と書けばオーナー。⚠️ オーナーとメンバーの両方に部分一致すると候補一覧のエラーになるため、フルネームか assignee_id を使う' },
102
116
  project_id: { type: 'string', description: 'このタスクを紐づけるプロジェクトのID(list_projects で取得したUUID)' },
103
117
  notify_assignee: { type: 'boolean', description: '担当者にChatworkで通知するか(デフォルト: false。trueで通知)' },
104
118
  notify_chatwork_setting_id: { type: 'string', description: '担当者通知の送信先ChatworkグループID(list_chatwork_settings で取得。未指定時は自動選択)' },
@@ -120,7 +134,7 @@ const tools = [
120
134
  due_date: { type: 'string', description: '新しい期限(manual のみ、null で期限解除)' },
121
135
  status: { type: 'string', description: 'ステータス変更: pending/done/dismissed' },
122
136
  assignee_id: { type: 'string', description: '担当者のメンバーID(list_team_members のUUID。空文字で担当者解除)' },
123
- assignee_name: { type: 'string', description: '担当者の名前(部分一致)。"解除"で担当者を外す。' },
137
+ assignee_name: { type: 'string', description: '担当者の名前(部分一致)。"解除"で担当者を外す。オーナー(APIキーの持ち主)も名前で指定でき、"自分" と書けばオーナー。⚠️ オーナーとメンバーの両方に部分一致すると候補一覧のエラーになるため、フルネームか assignee_id を使う' },
124
138
  project_id: { type: 'string', description: '紐づけるプロジェクトのID(list_projects のUUID。空文字で解除)' },
125
139
  },
126
140
  required: ['id'],
@@ -183,11 +197,28 @@ const handlers = {
183
197
  return `✅ ${data.message}\nID: ${data.id}`;
184
198
  },
185
199
 
200
+ async list_team_members() {
201
+ const data = await callApi('/team-members');
202
+ if (!data.members || data.members.length === 0) return 'チームメンバーが登録されていません。';
203
+ // ⚠️ オーナーとメンバーを見分けられるようにする(同姓のとき assignee_id を選ぶ手がかり)
204
+ const ROLE_JA = { owner: 'オーナー', member: 'メンバー', admin: '管理者' };
205
+ const lines = data.members.map(m =>
206
+ `${m.is_active ? '•' : '(無効)'} [${m.id}] ${m.name}(${ROLE_JA[m.role] || m.role || 'メンバー'})`
207
+ );
208
+ return `チームメンバー(${data.count}名):\n\n${lines.join('\n')}\n\n` +
209
+ 'このIDを list_tasks / create_task / update_task の assignee_id に指定できます。\n' +
210
+ '※ 自分(APIキーの持ち主=オーナー)に割り当てるなら assignee_name:"自分" でも指定できます。';
211
+ },
212
+
186
213
  async list_tasks(args) {
187
214
  const params = new URLSearchParams();
188
215
  if (args.status) params.set('status', args.status);
189
216
  if (args.type) params.set('type', args.type);
190
217
  if (args.limit) params.set('limit', String(args.limit));
218
+ // ⚠️ 未指定のものは1つもクエリに載せない=サーバー側も従来と同じSQLになる
219
+ if (args.assignee_id) params.set('assignee_id', String(args.assignee_id));
220
+ if (args.assignee_name) params.set('assignee_name', String(args.assignee_name));
221
+ if (args.unassigned === true) params.set('unassigned', 'true');
191
222
  const data = await callApi(`/tasks?${params}`);
192
223
  if (!data.tasks || data.tasks.length === 0) return 'タスクがありません。';
193
224
  const statusIcon = { pending: '⏳', done: '✅', dismissed: '🚫', approved: '✔', rejected: '✗' };
@@ -196,6 +227,9 @@ const handlers = {
196
227
  ` [${t.status}/${t.priority}]` +
197
228
  (t.due_date ? ` 期限:${t.due_date.slice(0, 10)}` : '') +
198
229
  (t.type !== 'manual' ? ` (${t.type})` : '') +
230
+ // ⚠️ 未設定でも「なし」を出す(依頼の条件: どのタスクタイプでもエラーにせず「なし」と表示)。
231
+ // 行末への追記なので既存項目の並び・書式は変わらない
232
+ ` 担当:${t.assignee_name || 'なし'}` +
199
233
  (t.body ? `\n ${t.body.slice(0, 60)}${t.body.length > 60 ? '…' : ''}` : '')
200
234
  );
201
235
  return `タスク一覧(${data.count}件):\n\n${lines.join('\n')}`;
@@ -206,6 +240,7 @@ const handlers = {
206
240
  const parts = [
207
241
  `タイトル: ${data.title}`, `ステータス: ${data.status}`,
208
242
  `優先度: ${data.priority}`, `タイプ: ${data.type}`,
243
+ `担当者: ${data.assignee_name || 'なし'}`,
209
244
  data.due_date ? `期限: ${data.due_date.slice(0, 16)}` : '',
210
245
  data.body ? `\n詳細:\n${data.body}` : '',
211
246
  data.content ? `\n内容:\n${data.content}` : '',
package/domains/skills.js CHANGED
@@ -294,6 +294,26 @@ Claude Code はその指示を読んで続けて prepare_skill(X) を呼び出
294
294
  required: ['id'],
295
295
  },
296
296
  },
297
+ {
298
+ name: 'save_skill_default_params',
299
+ description: `スキルのパラメータ設定を「パターン」として保存します。【書き込み権限付きキーが必要】
300
+
301
+ 同じスキルを用途別に使い分けたいとき(例:「A社向け」「短文版」)に、名前を付けて複数保存できます。
302
+ 保存した値は、そのスキルを開いたときの入力欄と起動コードの初期値になります。
303
+
304
+ ⚠️ 保存先は実行したワークスペースのものです。他のお客様には一切表示されません。
305
+ Admin公開スキルなど自分が所有していないスキルにも、自分用として保存できます。
306
+ 1スキルにつき20件まで。同じ名前で保存すると上書きされます。`,
307
+ inputSchema: {
308
+ type: 'object',
309
+ properties: {
310
+ id: { type: 'string', description: 'スキルID(list_skillsで確認)。skill_id という名前で渡しても受け付けます' },
311
+ params: { type: 'object', description: 'パラメータ名と値のマップ。get_skill で parameters を確認してから渡す' },
312
+ param_preset_name: { type: 'string', description: 'パターン名(省略時は「保存した設定」)。名前を変えると別のパターンとして保存され、同じ名前なら上書き' },
313
+ },
314
+ required: ['id', 'params'],
315
+ },
316
+ },
297
317
  {
298
318
  name: 'list_skill_versions',
299
319
  description: `スキルのバージョン履歴一覧を取得します。
@@ -603,6 +623,14 @@ const handlers = {
603
623
  return lines.join('\n');
604
624
  },
605
625
 
626
+ save_skill_default_params: async ({ id, skill_id, params, param_preset_name }) => {
627
+ const d = await callApi(`/skills/${id || skill_id}/default-params`, {
628
+ method: 'PATCH',
629
+ body: JSON.stringify({ params, ...(param_preset_name ? { param_preset_name } : {}) }),
630
+ });
631
+ return `✅ ${d.message || 'パラメータを保存しました'}`;
632
+ },
633
+
606
634
  list_skill_versions: async ({ id, skill_id }) => {
607
635
  const { versions } = await callApi(`/skills/${id || skill_id}/versions`);
608
636
  if (!versions || versions.length === 0) return 'バージョン履歴はまだありません。create_skill_version でバージョンを保存できます。';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "owner-clone-ai-mcp",
3
- "version": "1.75.0",
3
+ "version": "1.77.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": {