Skip to main content

subcog/mcp/tools/
definitions.rs

1//! Tool definitions for MCP tools.
2//!
3//! Contains the JSON Schema definitions for all subcog tools.
4
5use super::ToolDefinition;
6
7/// Defines the capture tool.
8pub fn capture_tool() -> ToolDefinition {
9    ToolDefinition {
10        name: "subcog_capture".to_string(),
11        description: "Capture a memory (decision, learning, pattern, etc.) for future recall"
12            .to_string(),
13        input_schema: serde_json::json!({
14            "type": "object",
15            "properties": {
16                "content": {
17                    "type": "string",
18                    "description": "The memory content to capture"
19                },
20                "namespace": {
21                    "type": "string",
22                    "description": "Memory category: decisions, patterns, learnings, context, tech-debt, apis, config, security, performance, testing",
23                    "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
24                },
25                "tags": {
26                    "type": "array",
27                    "items": { "type": "string" },
28                    "description": "Optional tags for categorization"
29                },
30                "source": {
31                    "type": "string",
32                    "description": "Optional source reference (file path, URL)"
33                },
34                "ttl": {
35                    "type": "string",
36                    "description": "Optional TTL for automatic expiration. Supports: '7d' (days), '24h' (hours), '60m' (minutes), '3600s' or '3600' (seconds), '0' (never expire)"
37                },
38                "domain": {
39                    "type": "string",
40                    "description": "Storage scope: 'project' (default, stored with project context), 'user' (global across all projects), 'org' (organization-shared)",
41                    "enum": ["project", "user", "org"],
42                    "default": "project"
43                }
44            },
45            "required": ["content", "namespace"]
46        }),
47    }
48}
49
50/// Defines the recall tool.
51///
52/// When `query` is omitted, behaves like `subcog_list` and returns all memories
53/// matching the filter criteria (with pagination support).
54pub fn recall_tool() -> ToolDefinition {
55    ToolDefinition {
56        name: "subcog_recall".to_string(),
57        description: "Search for relevant memories using semantic and text search, or list all memories when no query is provided. Returns normalized scores (0.0-1.0 where 1.0 is the best match) with raw RRF scores shown in parentheses for debugging. Subsumes subcog_list functionality.".to_string(),
58        input_schema: serde_json::json!({
59            "type": "object",
60            "additionalProperties": false,
61            "properties": {
62                "query": {
63                    "type": "string",
64                    "description": "The search query. If omitted, lists all memories matching the filter criteria."
65                },
66                "filter": {
67                    "type": "string",
68                    "description": "Filter query using GitHub-style syntax: ns:decisions tag:rust -tag:test since:7d source:src/*"
69                },
70                "namespace": {
71                    "type": "string",
72                    "description": "Optional: Filter by namespace (deprecated, use filter instead)",
73                    "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
74                },
75                "mode": {
76                    "type": "string",
77                    "description": "Search mode: hybrid (default), vector, text",
78                    "enum": ["hybrid", "vector", "text"]
79                },
80                "detail": {
81                    "type": "string",
82                    "description": "Detail level: light (frontmatter only), medium (+ summary), everything (full content). Default: medium",
83                    "enum": ["light", "medium", "everything"]
84                },
85                "limit": {
86                    "type": "integer",
87                    "description": "Maximum number of results (default: 10 for search, 50 for list)",
88                    "minimum": 1,
89                    "maximum": 1000
90                },
91                "entity": {
92                    "type": "string",
93                    "description": "Filter by entity names (memories mentioning these entities). Comma-separated for OR logic (e.g., 'PostgreSQL,Redis')"
94                },
95                "offset": {
96                    "type": "integer",
97                    "description": "Offset for pagination (default: 0). Used when listing without query.",
98                    "minimum": 0,
99                    "default": 0
100                },
101                "user_id": {
102                    "type": "string",
103                    "description": "Filter by user ID (for multi-tenant scoping)"
104                },
105                "agent_id": {
106                    "type": "string",
107                    "description": "Filter by agent ID (for multi-agent scoping)"
108                }
109            },
110            "required": []
111        }),
112    }
113}
114
115/// Defines the status tool.
116pub fn status_tool() -> ToolDefinition {
117    ToolDefinition {
118        name: "subcog_status".to_string(),
119        description: "Get memory system status and statistics".to_string(),
120        input_schema: serde_json::json!({
121            "type": "object",
122            "properties": {},
123            "required": []
124        }),
125    }
126}
127
128/// Defines the `prompt_understanding` tool.
129pub fn prompt_understanding_tool() -> ToolDefinition {
130    ToolDefinition {
131        name: "prompt_understanding".to_string(),
132        description: "Detailed guidance for using Subcog MCP tools effectively".to_string(),
133        input_schema: serde_json::json!({
134            "type": "object",
135            "properties": {},
136            "required": []
137        }),
138    }
139}
140
141/// Defines the namespaces tool.
142pub fn namespaces_tool() -> ToolDefinition {
143    ToolDefinition {
144        name: "subcog_namespaces".to_string(),
145        description: "List available memory namespaces and their descriptions".to_string(),
146        input_schema: serde_json::json!({
147            "type": "object",
148            "properties": {},
149            "required": []
150        }),
151    }
152}
153
154/// Defines the consolidate tool.
155pub fn consolidate_tool() -> ToolDefinition {
156    ToolDefinition {
157        name: "subcog_consolidate".to_string(),
158        description: "Consolidate related memories by finding semantic clusters and creating summary nodes. Returns consolidation statistics.".to_string(),
159        input_schema: serde_json::json!({
160            "type": "object",
161            "properties": {
162                "namespaces": {
163                    "type": "array",
164                    "items": {
165                        "type": "string",
166                        "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
167                    },
168                    "description": "Namespaces to consolidate (optional, defaults to all)"
169                },
170                "days": {
171                    "type": "integer",
172                    "description": "Time window in days for memories to consolidate (optional)",
173                    "minimum": 1
174                },
175                "dry_run": {
176                    "type": "boolean",
177                    "description": "If true, show what would be consolidated without making changes",
178                    "default": false
179                },
180                "min_memories": {
181                    "type": "integer",
182                    "description": "Minimum number of memories required to form a group (optional, default: 3)",
183                    "minimum": 2
184                },
185                "similarity": {
186                    "type": "number",
187                    "description": "Similarity threshold 0.0-1.0 for grouping related memories (optional, default: 0.7)",
188                    "minimum": 0.0,
189                    "maximum": 1.0
190                }
191            },
192            "required": []
193        }),
194    }
195}
196
197/// Defines the get summary tool.
198pub fn get_summary_tool() -> ToolDefinition {
199    ToolDefinition {
200        name: "subcog_get_summary".to_string(),
201        description: "Retrieve a summary node and its linked source memories. Uses edge relationships to show which memories were consolidated into the summary.".to_string(),
202        input_schema: serde_json::json!({
203            "type": "object",
204            "properties": {
205                "memory_id": {
206                    "type": "string",
207                    "description": "ID of the summary memory to retrieve"
208                }
209            },
210            "required": ["memory_id"]
211        }),
212    }
213}
214
215/// Defines the enrich tool.
216pub fn enrich_tool() -> ToolDefinition {
217    ToolDefinition {
218        name: "subcog_enrich".to_string(),
219        description: "Enrich a memory with better structure, tags, and context using LLM. Uses MCP sampling to request LLM completion.".to_string(),
220        input_schema: serde_json::json!({
221            "type": "object",
222            "properties": {
223                "memory_id": {
224                    "type": "string",
225                    "description": "ID of the memory to enrich"
226                },
227                "enrich_tags": {
228                    "type": "boolean",
229                    "description": "Generate or improve tags",
230                    "default": true
231                },
232                "enrich_structure": {
233                    "type": "boolean",
234                    "description": "Restructure content for clarity",
235                    "default": true
236                },
237                "add_context": {
238                    "type": "boolean",
239                    "description": "Add inferred context and rationale",
240                    "default": false
241                }
242            },
243            "required": ["memory_id"]
244        }),
245    }
246}
247
248/// Defines the sync tool.
249///
250/// **DEPRECATED**: `SQLite` is now the authoritative storage. This tool is retained
251/// for backward compatibility but is a no-op. Will be removed in a future version.
252pub fn sync_tool() -> ToolDefinition {
253    ToolDefinition {
254        name: "subcog_sync".to_string(),
255        description: "[DEPRECATED] Sync memories with git remote. No longer needed as SQLite is now authoritative storage. This tool is a no-op and will be removed in a future version.".to_string(),
256        input_schema: serde_json::json!({
257            "type": "object",
258            "properties": {
259                "direction": {
260                    "type": "string",
261                    "description": "Sync direction: push (upload), fetch (download), full (both)",
262                    "enum": ["push", "fetch", "full"],
263                    "default": "full"
264                }
265            },
266            "required": []
267        }),
268    }
269}
270
271/// Defines the reindex tool.
272pub fn reindex_tool() -> ToolDefinition {
273    ToolDefinition {
274        name: "subcog_reindex".to_string(),
275        description: "Rebuild the search index from stored memories. Use when index is out of sync with stored memories.".to_string(),
276        input_schema: serde_json::json!({
277            "type": "object",
278            "properties": {
279                "repo_path": {
280                    "type": "string",
281                    "description": "Path to git repository (default: current directory)"
282                }
283            },
284            "required": []
285        }),
286    }
287}
288
289/// Defines the GDPR data export tool.
290///
291/// Implements GDPR Article 20 (Right to Data Portability).
292pub fn gdpr_export_tool() -> ToolDefinition {
293    ToolDefinition {
294        name: "subcog_gdpr_export".to_string(),
295        description: "Export all user data in a portable JSON format (GDPR Article 20 - Right to Data Portability). Returns all memories with metadata for download or transfer to another system.".to_string(),
296        input_schema: serde_json::json!({
297            "type": "object",
298            "properties": {},
299            "required": []
300        }),
301    }
302}
303
304// ============================================================================
305// Prompt Management Tools
306// ============================================================================
307
308/// Defines the consolidated `subcog_prompts` tool.
309///
310/// Combines all prompt operations into a single action-based tool.
311pub fn prompts_tool() -> ToolDefinition {
312    ToolDefinition {
313        name: "subcog_prompts".to_string(),
314        description: "Manage prompt templates. Actions: save, list, get, run, delete.".to_string(),
315        input_schema: serde_json::json!({
316            "type": "object",
317            "properties": {
318                "action": {
319                    "type": "string",
320                    "description": "Operation to perform",
321                    "enum": ["save", "list", "get", "run", "delete"]
322                },
323                "name": {
324                    "type": "string",
325                    "description": "Prompt name (required for save/get/run/delete)"
326                },
327                "content": {
328                    "type": "string",
329                    "description": "Prompt content with {{variable}} placeholders (for save, required if file_path not provided)"
330                },
331                "file_path": {
332                    "type": "string",
333                    "description": "Path to file containing prompt (for save, alternative to content)"
334                },
335                "description": {
336                    "type": "string",
337                    "description": "Human-readable description (for save)"
338                },
339                "tags": {
340                    "type": "array",
341                    "items": { "type": "string" },
342                    "description": "Tags for categorization (for save/list)"
343                },
344                "domain": {
345                    "type": "string",
346                    "description": "Storage scope: project (default), user, or org",
347                    "enum": ["project", "user", "org"],
348                    "default": "project"
349                },
350                "variables_def": {
351                    "type": "array",
352                    "description": "Variable definitions with metadata (for save)",
353                    "items": {
354                        "type": "object",
355                        "properties": {
356                            "name": { "type": "string" },
357                            "description": { "type": "string" },
358                            "default": { "type": "string" },
359                            "required": { "type": "boolean", "default": true }
360                        },
361                        "required": ["name"]
362                    }
363                },
364                "variables": {
365                    "type": "object",
366                    "description": "Variable values to substitute (for run)",
367                    "additionalProperties": { "type": "string" }
368                },
369                "skip_enrichment": {
370                    "type": "boolean",
371                    "description": "Skip LLM-powered metadata enrichment (for save)",
372                    "default": false
373                },
374                "name_pattern": {
375                    "type": "string",
376                    "description": "Filter by name pattern (for list, glob-style)"
377                },
378                "limit": {
379                    "type": "integer",
380                    "description": "Maximum number of results (for list)",
381                    "minimum": 1,
382                    "maximum": 100,
383                    "default": 20
384                }
385            },
386            "required": ["action"]
387        }),
388    }
389}
390
391/// Defines the prompt.save tool (legacy).
392pub fn prompt_save_tool() -> ToolDefinition {
393    ToolDefinition {
394        name: "prompt_save".to_string(),
395        description: "Save a user-defined prompt template. Provide either 'content' or 'file_path' (not both)".to_string(),
396        input_schema: serde_json::json!({
397            "type": "object",
398            "properties": {
399                "name": {
400                    "type": "string",
401                    "description": "Unique prompt name (kebab-case, e.g., 'code-review')"
402                },
403                "content": {
404                    "type": "string",
405                    "description": "Prompt content with {{variable}} placeholders (required if file_path not provided)"
406                },
407                "file_path": {
408                    "type": "string",
409                    "description": "Path to file containing prompt (alternative to content)"
410                },
411                "description": {
412                    "type": "string",
413                    "description": "Human-readable description of the prompt"
414                },
415                "tags": {
416                    "type": "array",
417                    "items": { "type": "string" },
418                    "description": "Tags for categorization and search"
419                },
420                "domain": {
421                    "type": "string",
422                    "description": "Storage scope: project (default), user, or org",
423                    "enum": ["project", "user", "org"],
424                    "default": "project"
425                },
426                "variables": {
427                    "type": "array",
428                    "description": "Explicit variable definitions with metadata",
429                    "items": {
430                        "type": "object",
431                        "properties": {
432                            "name": { "type": "string", "description": "Variable name (without braces)" },
433                            "description": { "type": "string", "description": "Human-readable description" },
434                            "default": { "type": "string", "description": "Default value if not provided" },
435                            "required": { "type": "boolean", "default": true, "description": "Whether variable is required" }
436                        },
437                        "required": ["name"]
438                    }
439                },
440                "skip_enrichment": {
441                    "type": "boolean",
442                    "description": "Skip LLM-powered metadata enrichment (default: false)",
443                    "default": false
444                }
445            },
446            "required": ["name"],
447            "additionalProperties": false
448        }),
449    }
450}
451
452/// Defines the prompt.list tool.
453pub fn prompt_list_tool() -> ToolDefinition {
454    ToolDefinition {
455        name: "prompt_list".to_string(),
456        description: "List saved prompt templates with optional filtering".to_string(),
457        input_schema: serde_json::json!({
458            "type": "object",
459            "properties": {
460                "domain": {
461                    "type": "string",
462                    "description": "Filter by domain scope",
463                    "enum": ["project", "user", "org"]
464                },
465                "tags": {
466                    "type": "array",
467                    "items": { "type": "string" },
468                    "description": "Filter by tags (AND logic - must have all)"
469                },
470                "name_pattern": {
471                    "type": "string",
472                    "description": "Filter by name pattern (glob-style, e.g., 'code-*')"
473                },
474                "limit": {
475                    "type": "integer",
476                    "description": "Maximum number of results",
477                    "minimum": 1,
478                    "maximum": 100,
479                    "default": 20
480                }
481            },
482            "required": []
483        }),
484    }
485}
486
487/// Defines the prompt.get tool.
488pub fn prompt_get_tool() -> ToolDefinition {
489    ToolDefinition {
490        name: "prompt_get".to_string(),
491        description: "Get a prompt template by name".to_string(),
492        input_schema: serde_json::json!({
493            "type": "object",
494            "properties": {
495                "name": {
496                    "type": "string",
497                    "description": "Prompt name to retrieve"
498                },
499                "domain": {
500                    "type": "string",
501                    "description": "Domain to search (if not specified, searches Project → User → Org)",
502                    "enum": ["project", "user", "org"]
503                }
504            },
505            "required": ["name"]
506        }),
507    }
508}
509
510/// Defines the prompt.run tool.
511pub fn prompt_run_tool() -> ToolDefinition {
512    ToolDefinition {
513        name: "prompt_run".to_string(),
514        description: "Run a saved prompt, substituting variable values".to_string(),
515        input_schema: serde_json::json!({
516            "type": "object",
517            "properties": {
518                "name": {
519                    "type": "string",
520                    "description": "Prompt name to run"
521                },
522                "variables": {
523                    "type": "object",
524                    "description": "Variable values to substitute (key: value pairs)",
525                    "additionalProperties": { "type": "string" }
526                },
527                "domain": {
528                    "type": "string",
529                    "description": "Domain to search for the prompt",
530                    "enum": ["project", "user", "org"]
531                }
532            },
533            "required": ["name"]
534        }),
535    }
536}
537
538/// Defines the prompt.delete tool.
539pub fn prompt_delete_tool() -> ToolDefinition {
540    ToolDefinition {
541        name: "prompt_delete".to_string(),
542        description: "Delete a saved prompt template".to_string(),
543        input_schema: serde_json::json!({
544            "type": "object",
545            "properties": {
546                "name": {
547                    "type": "string",
548                    "description": "Prompt name to delete"
549                },
550                "domain": {
551                    "type": "string",
552                    "description": "Domain scope to delete from (required for safety)",
553                    "enum": ["project", "user", "org"]
554                }
555            },
556            "required": ["name", "domain"]
557        }),
558    }
559}
560
561// ============================================================================
562// Core CRUD Tools (Industry Parity: Mem0, Zep, LangMem)
563// ============================================================================
564
565/// Defines the get tool for direct memory retrieval by ID.
566///
567/// This is a fundamental CRUD operation present in all major memory systems:
568/// - Mem0: `get(memory_id)`
569/// - Zep: `get_memory(session_id, memory_id)`
570/// - `LangMem`: `get_memories()`
571pub fn get_tool() -> ToolDefinition {
572    ToolDefinition {
573        name: "subcog_get".to_string(),
574        description: "Get a memory by its ID. Returns the full memory content, metadata, and URN."
575            .to_string(),
576        input_schema: serde_json::json!({
577            "type": "object",
578            "properties": {
579                "memory_id": {
580                    "type": "string",
581                    "description": "The ID of the memory to retrieve"
582                }
583            },
584            "required": ["memory_id"]
585        }),
586    }
587}
588
589/// Defines the delete tool for removing memories.
590///
591/// Supports both soft delete (tombstone) and hard delete (permanent).
592/// Defaults to soft delete for safety, matching the CLI behavior.
593pub fn delete_tool() -> ToolDefinition {
594    ToolDefinition {
595        name: "subcog_delete".to_string(),
596        description: "Delete a memory by its ID. Defaults to soft delete (tombstone) which can be restored. Use hard=true for permanent deletion.".to_string(),
597        input_schema: serde_json::json!({
598            "type": "object",
599            "properties": {
600                "memory_id": {
601                    "type": "string",
602                    "description": "The ID of the memory to delete"
603                },
604                "hard": {
605                    "type": "boolean",
606                    "description": "If true, permanently delete the memory. If false (default), soft delete (tombstone) - can be restored later.",
607                    "default": false
608                }
609            },
610            "required": ["memory_id"]
611        }),
612    }
613}
614
615/// Defines the update tool for modifying existing memories.
616///
617/// Allows partial updates to content and/or tags. Follows the industry
618/// pattern of partial updates (Mem0 `update`, `LangMem` `update`).
619pub fn update_tool() -> ToolDefinition {
620    ToolDefinition {
621        name: "subcog_update".to_string(),
622        description: "Update an existing memory's content and/or tags. Provide only the fields you want to change.".to_string(),
623        input_schema: serde_json::json!({
624            "type": "object",
625            "properties": {
626                "memory_id": {
627                    "type": "string",
628                    "description": "The ID of the memory to update"
629                },
630                "content": {
631                    "type": "string",
632                    "description": "New content for the memory (optional - omit to keep existing)"
633                },
634                "tags": {
635                    "type": "array",
636                    "items": { "type": "string" },
637                    "description": "New tags for the memory (optional - omit to keep existing). Replaces all existing tags when provided."
638                }
639            },
640            "required": ["memory_id"]
641        }),
642    }
643}
644
645/// Defines the list tool for listing all memories.
646///
647/// Lists memories with optional filtering and pagination.
648/// Matches Mem0's `get_all()` and Zep's `list_memories()` patterns.
649pub fn list_tool() -> ToolDefinition {
650    ToolDefinition {
651        name: "subcog_list".to_string(),
652        description: "List all memories with optional filtering and pagination. Unlike recall, this doesn't require a search query.".to_string(),
653        input_schema: serde_json::json!({
654            "type": "object",
655            "properties": {
656                "filter": {
657                    "type": "string",
658                    "description": "GitHub-style filter query: ns:decisions tag:rust -tag:test status:active"
659                },
660                "limit": {
661                    "type": "integer",
662                    "description": "Maximum number of results (default: 50, max: 1000)",
663                    "minimum": 1,
664                    "maximum": 1000,
665                    "default": 50
666                },
667                "offset": {
668                    "type": "integer",
669                    "description": "Offset for pagination (default: 0)",
670                    "minimum": 0,
671                    "default": 0
672                },
673                "user_id": {
674                    "type": "string",
675                    "description": "Filter by user ID (for multi-tenant scoping)"
676                },
677                "agent_id": {
678                    "type": "string",
679                    "description": "Filter by agent ID (for multi-agent scoping)"
680                }
681            },
682            "required": []
683        }),
684    }
685}
686
687/// Defines the `delete_all` tool for bulk deletion.
688///
689/// Bulk deletes memories matching filter criteria with dry-run safety.
690/// Implements Mem0's `delete_all()` pattern.
691pub fn delete_all_tool() -> ToolDefinition {
692    ToolDefinition {
693        name: "subcog_delete_all".to_string(),
694        description: "Bulk delete memories matching filter criteria. Defaults to dry-run mode for safety - set dry_run=false to execute.".to_string(),
695        input_schema: serde_json::json!({
696            "type": "object",
697            "properties": {
698                "filter": {
699                    "type": "string",
700                    "description": "GitHub-style filter query: ns:decisions tag:deprecated -tag:important"
701                },
702                "dry_run": {
703                    "type": "boolean",
704                    "description": "If true (default), show what would be deleted without making changes",
705                    "default": true
706                },
707                "hard": {
708                    "type": "boolean",
709                    "description": "If true, permanently delete. If false (default), soft delete (tombstone).",
710                    "default": false
711                },
712                "user_id": {
713                    "type": "string",
714                    "description": "Filter by user ID for scoped deletion"
715                }
716            },
717            "required": []
718        }),
719    }
720}
721
722/// Defines the restore tool for recovering soft-deleted memories.
723///
724/// Restores a tombstoned memory back to active status.
725/// Implements the inverse of soft delete for data recovery.
726pub fn restore_tool() -> ToolDefinition {
727    ToolDefinition {
728        name: "subcog_restore".to_string(),
729        description:
730            "Restore a soft-deleted (tombstoned) memory. Returns the memory to active status."
731                .to_string(),
732        input_schema: serde_json::json!({
733            "type": "object",
734            "properties": {
735                "memory_id": {
736                    "type": "string",
737                    "description": "The ID of the tombstoned memory to restore"
738                }
739            },
740            "required": ["memory_id"]
741        }),
742    }
743}
744
745/// Defines the history tool for memory change audit trail.
746///
747/// Retrieves change history for a memory by querying the event log.
748/// Provides audit trail visibility for compliance and debugging.
749pub fn history_tool() -> ToolDefinition {
750    ToolDefinition {
751        name: "subcog_history".to_string(),
752        description: "Get the change history for a memory. Shows creation, updates, and deletions from the audit log.".to_string(),
753        input_schema: serde_json::json!({
754            "type": "object",
755            "properties": {
756                "memory_id": {
757                    "type": "string",
758                    "description": "The ID of the memory to get history for"
759                },
760                "limit": {
761                    "type": "integer",
762                    "description": "Maximum number of events to return (default: 20)",
763                    "minimum": 1,
764                    "maximum": 100,
765                    "default": 20
766                }
767            },
768            "required": ["memory_id"]
769        }),
770    }
771}
772
773// ============================================================================
774// Graph / Knowledge Graph Tools
775// ============================================================================
776
777/// Defines the entities tool for entity CRUD operations.
778///
779/// Provides operations to create, read, update, and delete entities
780/// in the knowledge graph.
781pub fn entities_tool() -> ToolDefinition {
782    ToolDefinition {
783        name: "subcog_entities".to_string(),
784        description: "Manage entities in the knowledge graph. Supports CRUD operations for people, organizations, technologies, concepts, and files.".to_string(),
785        input_schema: serde_json::json!({
786            "type": "object",
787            "properties": {
788                "action": {
789                    "type": "string",
790                    "description": "Operation to perform",
791                    "enum": ["create", "get", "list", "delete"]
792                },
793                "entity_id": {
794                    "type": "string",
795                    "description": "Entity ID (required for get/delete)"
796                },
797                "name": {
798                    "type": "string",
799                    "description": "Entity name (required for create)"
800                },
801                "entity_type": {
802                    "type": "string",
803                    "description": "Type of entity",
804                    "enum": ["Person", "Organization", "Technology", "Concept", "File"]
805                },
806                "aliases": {
807                    "type": "array",
808                    "items": { "type": "string" },
809                    "description": "Alternative names for the entity"
810                },
811                "limit": {
812                    "type": "integer",
813                    "description": "Maximum results for list operation (default: 20)",
814                    "minimum": 1,
815                    "maximum": 100,
816                    "default": 20
817                }
818            },
819            "required": ["action"]
820        }),
821    }
822}
823
824/// Defines the relationships tool for relationship CRUD operations.
825///
826/// Provides operations to create, read, and delete relationships
827/// between entities in the knowledge graph.
828pub fn relationships_tool() -> ToolDefinition {
829    ToolDefinition {
830        name: "subcog_relationships".to_string(),
831        description: "Manage relationships between entities in the knowledge graph. Supports creating, querying, and deleting relationships like WorksAt, Uses, Created, etc.".to_string(),
832        input_schema: serde_json::json!({
833            "type": "object",
834            "properties": {
835                "action": {
836                    "type": "string",
837                    "description": "Operation to perform",
838                    "enum": ["create", "get", "list", "delete"]
839                },
840                "from_entity": {
841                    "type": "string",
842                    "description": "Source entity ID (required for create)"
843                },
844                "to_entity": {
845                    "type": "string",
846                    "description": "Target entity ID (required for create)"
847                },
848                "relationship_type": {
849                    "type": "string",
850                    "description": "Type of relationship",
851                    "enum": ["WorksAt", "Created", "Uses", "Implements", "PartOf", "RelatesTo", "MentionedIn", "Supersedes", "ConflictsWith"]
852                },
853                "entity_id": {
854                    "type": "string",
855                    "description": "Entity ID to get relationships for (for get/list)"
856                },
857                "direction": {
858                    "type": "string",
859                    "description": "Relationship direction for get/list",
860                    "enum": ["outgoing", "incoming", "both"],
861                    "default": "both"
862                },
863                "limit": {
864                    "type": "integer",
865                    "description": "Maximum results (default: 20)",
866                    "minimum": 1,
867                    "maximum": 100,
868                    "default": 20
869                }
870            },
871            "required": ["action"]
872        }),
873    }
874}
875
876/// Defines the graph query tool for traversing the knowledge graph.
877///
878/// Enables graph traversal operations like finding neighbors,
879/// paths between entities, and subgraph extraction.
880pub fn graph_query_tool() -> ToolDefinition {
881    ToolDefinition {
882        name: "subcog_graph_query".to_string(),
883        description: "Query and traverse the knowledge graph. Find paths between entities, get neighbors at various depths, and explore connections.".to_string(),
884        input_schema: serde_json::json!({
885            "type": "object",
886            "properties": {
887                "operation": {
888                    "type": "string",
889                    "description": "Query operation to perform",
890                    "enum": ["neighbors", "path", "stats"]
891                },
892                "entity_id": {
893                    "type": "string",
894                    "description": "Starting entity ID (required for neighbors)"
895                },
896                "from_entity": {
897                    "type": "string",
898                    "description": "Source entity ID (required for path)"
899                },
900                "to_entity": {
901                    "type": "string",
902                    "description": "Target entity ID (required for path)"
903                },
904                "depth": {
905                    "type": "integer",
906                    "description": "Traversal depth for neighbors/path (default: 2, max: 5)",
907                    "minimum": 1,
908                    "maximum": 5,
909                    "default": 2
910                }
911            },
912            "required": ["operation"]
913        }),
914    }
915}
916
917/// Defines the extract entities tool for LLM-powered entity extraction.
918///
919/// Extracts entities and relationships from text content using
920/// LLM analysis with pattern-based fallback.
921pub fn extract_entities_tool() -> ToolDefinition {
922    ToolDefinition {
923        name: "subcog_extract_entities".to_string(),
924        description: "Extract entities and relationships from text using LLM. Identifies people, organizations, technologies, concepts, and their relationships. Falls back to pattern-based extraction if LLM unavailable.".to_string(),
925        input_schema: serde_json::json!({
926            "type": "object",
927            "properties": {
928                "content": {
929                    "type": "string",
930                    "description": "Text content to extract entities from"
931                },
932                "store": {
933                    "type": "boolean",
934                    "description": "Whether to store extracted entities in the graph (default: false)",
935                    "default": false
936                },
937                "memory_id": {
938                    "type": "string",
939                    "description": "Optional memory ID to link extracted entities to"
940                },
941                "min_confidence": {
942                    "type": "number",
943                    "description": "Minimum confidence threshold (0.0-1.0, default: 0.5)",
944                    "minimum": 0.0,
945                    "maximum": 1.0,
946                    "default": 0.5
947                }
948            },
949            "required": ["content"]
950        }),
951    }
952}
953
954/// Defines the entity merge tool for deduplicating entities.
955///
956/// Merges duplicate or similar entities into a single canonical entity,
957/// preserving relationships and mentions.
958pub fn entity_merge_tool() -> ToolDefinition {
959    ToolDefinition {
960        name: "subcog_entity_merge".to_string(),
961        description: "Merge duplicate entities into a single canonical entity. Transfers all relationships and mentions to the merged entity. Use 'find_duplicates' to identify candidates first.".to_string(),
962        input_schema: serde_json::json!({
963            "type": "object",
964            "properties": {
965                "action": {
966                    "type": "string",
967                    "description": "Operation to perform",
968                    "enum": ["find_duplicates", "merge"]
969                },
970                "entity_id": {
971                    "type": "string",
972                    "description": "Entity ID to find duplicates for (for find_duplicates)"
973                },
974                "entity_ids": {
975                    "type": "array",
976                    "items": { "type": "string" },
977                    "description": "Entity IDs to merge (for merge, minimum 2)"
978                },
979                "canonical_name": {
980                    "type": "string",
981                    "description": "Name for the merged entity (required for merge)"
982                },
983                "threshold": {
984                    "type": "number",
985                    "description": "Similarity threshold for finding duplicates (0.0-1.0, default: 0.7)",
986                    "minimum": 0.0,
987                    "maximum": 1.0,
988                    "default": 0.7
989                }
990            },
991            "required": ["action"]
992        }),
993    }
994}
995
996/// Defines the relationship inference tool for discovering implicit relationships.
997///
998/// Uses LLM analysis to infer relationships between existing entities
999/// based on context and patterns.
1000pub fn relationship_infer_tool() -> ToolDefinition {
1001    ToolDefinition {
1002        name: "subcog_relationship_infer".to_string(),
1003        description: "Infer implicit relationships between entities using LLM analysis. Discovers connections based on entity types, names, and context. Falls back to heuristic-based inference if LLM unavailable.".to_string(),
1004        input_schema: serde_json::json!({
1005            "type": "object",
1006            "properties": {
1007                "entity_ids": {
1008                    "type": "array",
1009                    "items": { "type": "string" },
1010                    "description": "Entity IDs to analyze for relationships (optional, analyzes all recent if not provided)"
1011                },
1012                "store": {
1013                    "type": "boolean",
1014                    "description": "Whether to store inferred relationships in the graph (default: false)",
1015                    "default": false
1016                },
1017                "min_confidence": {
1018                    "type": "number",
1019                    "description": "Minimum confidence threshold for inferred relationships (0.0-1.0, default: 0.6)",
1020                    "minimum": 0.0,
1021                    "maximum": 1.0,
1022                    "default": 0.6
1023                },
1024                "limit": {
1025                    "type": "integer",
1026                    "description": "Maximum entities to analyze if entity_ids not provided (default: 50)",
1027                    "minimum": 1,
1028                    "maximum": 200,
1029                    "default": 50
1030                }
1031            },
1032            "required": []
1033        }),
1034    }
1035}
1036
1037/// Defines the graph visualize tool for generating graph visualizations.
1038///
1039/// Produces ASCII art, Mermaid diagrams, or DOT format representations
1040/// of the knowledge graph.
1041pub fn graph_visualize_tool() -> ToolDefinition {
1042    ToolDefinition {
1043        name: "subcog_graph_visualize".to_string(),
1044        description: "Visualize the knowledge graph or a subgraph. Generates Mermaid diagrams, DOT format, or ASCII art representation of entities and their relationships.".to_string(),
1045        input_schema: serde_json::json!({
1046            "type": "object",
1047            "properties": {
1048                "format": {
1049                    "type": "string",
1050                    "description": "Output format for visualization",
1051                    "enum": ["mermaid", "dot", "ascii"],
1052                    "default": "mermaid"
1053                },
1054                "entity_id": {
1055                    "type": "string",
1056                    "description": "Center visualization on this entity (optional)"
1057                },
1058                "depth": {
1059                    "type": "integer",
1060                    "description": "Depth of relationships to include from center entity (default: 2)",
1061                    "minimum": 1,
1062                    "maximum": 4,
1063                    "default": 2
1064                },
1065                "entity_types": {
1066                    "type": "array",
1067                    "items": {
1068                        "type": "string",
1069                        "enum": ["Person", "Organization", "Technology", "Concept", "File"]
1070                    },
1071                    "description": "Filter to specific entity types"
1072                },
1073                "relationship_types": {
1074                    "type": "array",
1075                    "items": {
1076                        "type": "string",
1077                        "enum": ["WorksAt", "Created", "Uses", "Implements", "PartOf", "RelatesTo", "MentionedIn", "Supersedes", "ConflictsWith"]
1078                    },
1079                    "description": "Filter to specific relationship types"
1080                },
1081                "limit": {
1082                    "type": "integer",
1083                    "description": "Maximum entities to include (default: 50)",
1084                    "minimum": 1,
1085                    "maximum": 200,
1086                    "default": 50
1087                }
1088            },
1089            "required": []
1090        }),
1091    }
1092}
1093
1094/// Defines the consolidated graph tool for knowledge graph operations.
1095///
1096/// Combines query (neighbors, path, stats) and visualize operations
1097/// into a single action-based tool. Reduces tool proliferation.
1098pub fn graph_tool() -> ToolDefinition {
1099    ToolDefinition {
1100        name: "subcog_graph".to_string(),
1101        description: "Consolidated knowledge graph operations. Query graph structure (neighbors, paths, stats) or generate visualizations. Combines subcog_graph_query and subcog_graph_visualize.".to_string(),
1102        input_schema: serde_json::json!({
1103            "type": "object",
1104            "additionalProperties": false,
1105            "properties": {
1106                "operation": {
1107                    "type": "string",
1108                    "description": "Graph operation to perform",
1109                    "enum": ["neighbors", "path", "stats", "visualize"]
1110                },
1111                "entity_id": {
1112                    "type": "string",
1113                    "description": "Entity ID for neighbors/visualize operations (center point)"
1114                },
1115                "from_entity": {
1116                    "type": "string",
1117                    "description": "Source entity ID for path operation"
1118                },
1119                "to_entity": {
1120                    "type": "string",
1121                    "description": "Target entity ID for path operation"
1122                },
1123                "depth": {
1124                    "type": "integer",
1125                    "description": "Depth of traversal for neighbors/visualize (default: 2)",
1126                    "minimum": 1,
1127                    "maximum": 4,
1128                    "default": 2
1129                },
1130                "format": {
1131                    "type": "string",
1132                    "description": "Output format for visualize operation",
1133                    "enum": ["mermaid", "dot", "ascii"],
1134                    "default": "mermaid"
1135                },
1136                "entity_types": {
1137                    "type": "array",
1138                    "items": {
1139                        "type": "string",
1140                        "enum": ["Person", "Organization", "Technology", "Concept", "File"]
1141                    },
1142                    "description": "Filter to specific entity types"
1143                },
1144                "relationship_types": {
1145                    "type": "array",
1146                    "items": {
1147                        "type": "string",
1148                        "enum": ["WorksAt", "Created", "Uses", "Implements", "PartOf", "RelatesTo", "MentionedIn", "Supersedes", "ConflictsWith"]
1149                    },
1150                    "description": "Filter to specific relationship types"
1151                },
1152                "limit": {
1153                    "type": "integer",
1154                    "description": "Maximum entities to include (default: 50)",
1155                    "minimum": 1,
1156                    "maximum": 200,
1157                    "default": 50
1158                }
1159            },
1160            "required": ["operation"]
1161        }),
1162    }
1163}
1164
1165/// Defines the init tool for session initialization.
1166///
1167/// Returns compressed XML with namespaces, domains, tools, status, and
1168/// optional recalled memories. Use `prompt_understanding` for full docs.
1169pub fn init_tool() -> ToolDefinition {
1170    ToolDefinition {
1171        name: "subcog_init".to_string(),
1172        description: "Initialize a Subcog session. Returns compressed XML with namespaces (with counts), domains, tools reference, status, and optional recalled memory previews. Call at session start. Use prompt_understanding tool for full markdown documentation.".to_string(),
1173        input_schema: serde_json::json!({
1174            "type": "object",
1175            "properties": {
1176                "include_recall": {
1177                    "type": "boolean",
1178                    "description": "Whether to recall project context (default: true)",
1179                    "default": true
1180                },
1181                "recall_query": {
1182                    "type": "string",
1183                    "description": "Custom recall query (default: 'project setup OR architecture OR conventions')"
1184                },
1185                "recall_limit": {
1186                    "type": "integer",
1187                    "description": "Maximum memories to recall (default: 5)",
1188                    "minimum": 1,
1189                    "maximum": 20,
1190                    "default": 5
1191                }
1192            },
1193            "required": []
1194        }),
1195    }
1196}
1197
1198// ============================================================================
1199// Context Template Tools
1200// ============================================================================
1201
1202/// Defines the consolidated `subcog_templates` tool.
1203///
1204/// Combines all context template operations into a single action-based tool.
1205pub fn templates_tool() -> ToolDefinition {
1206    ToolDefinition {
1207        name: "subcog_templates".to_string(),
1208        description: "Manage context templates for formatting memories. Actions: save, list, get, render, delete.".to_string(),
1209        input_schema: serde_json::json!({
1210            "type": "object",
1211            "properties": {
1212                "action": {
1213                    "type": "string",
1214                    "description": "Operation to perform",
1215                    "enum": ["save", "list", "get", "render", "delete"]
1216                },
1217                "name": {
1218                    "type": "string",
1219                    "description": "Template name (required for save/get/render/delete)"
1220                },
1221                "content": {
1222                    "type": "string",
1223                    "description": "Template content with {{variable}} placeholders and {{#each memories}} iteration (for save)"
1224                },
1225                "description": {
1226                    "type": "string",
1227                    "description": "Human-readable description (for save)"
1228                },
1229                "tags": {
1230                    "type": "array",
1231                    "items": { "type": "string" },
1232                    "description": "Tags for categorization (for save/list)"
1233                },
1234                "domain": {
1235                    "type": "string",
1236                    "description": "Storage scope: project (default), user, or org",
1237                    "enum": ["project", "user", "org"],
1238                    "default": "project"
1239                },
1240                "output_format": {
1241                    "type": "string",
1242                    "description": "Default output format (for save): markdown, json, or xml",
1243                    "enum": ["markdown", "json", "xml"],
1244                    "default": "markdown"
1245                },
1246                "variables_def": {
1247                    "type": "array",
1248                    "description": "Variable definitions with metadata (for save)",
1249                    "items": {
1250                        "type": "object",
1251                        "properties": {
1252                            "name": { "type": "string" },
1253                            "description": { "type": "string" },
1254                            "default": { "type": "string" },
1255                            "required": { "type": "boolean", "default": true }
1256                        },
1257                        "required": ["name"]
1258                    }
1259                },
1260                "variables": {
1261                    "type": "object",
1262                    "description": "Custom variable values for rendering (for render)",
1263                    "additionalProperties": { "type": "string" }
1264                },
1265                "name_pattern": {
1266                    "type": "string",
1267                    "description": "Filter by name pattern (for list, glob-style)"
1268                },
1269                "limit": {
1270                    "type": "integer",
1271                    "description": "Maximum results (for list) or memories (for render)",
1272                    "minimum": 1,
1273                    "maximum": 100,
1274                    "default": 20
1275                },
1276                "version": {
1277                    "type": "integer",
1278                    "description": "Specific version (for get/render/delete)",
1279                    "minimum": 1
1280                },
1281                "query": {
1282                    "type": "string",
1283                    "description": "Query string for memory search to populate template (for render)"
1284                },
1285                "namespaces": {
1286                    "type": "array",
1287                    "items": { "type": "string" },
1288                    "description": "Namespaces to filter memories (for render)"
1289                },
1290                "format": {
1291                    "type": "string",
1292                    "description": "Output format override (for render): markdown, json, or xml",
1293                    "enum": ["markdown", "json", "xml"]
1294                }
1295            },
1296            "required": ["action"]
1297        }),
1298    }
1299}
1300
1301/// Defines the `context_template_save` tool (legacy).
1302pub fn context_template_save_tool() -> ToolDefinition {
1303    ToolDefinition {
1304        name: "context_template_save".to_string(),
1305        description: "Save or update a context template for formatting memories. Templates support variable substitution ({{var}}), iteration ({{#each memories}}...{{/each}}), and multiple output formats.".to_string(),
1306        input_schema: serde_json::json!({
1307            "type": "object",
1308            "properties": {
1309                "name": {
1310                    "type": "string",
1311                    "description": "Template name (unique identifier)"
1312                },
1313                "content": {
1314                    "type": "string",
1315                    "description": "Template content with variable placeholders. Use {{var}} for variables, {{#each memories}}...{{/each}} for iteration over memories."
1316                },
1317                "description": {
1318                    "type": "string",
1319                    "description": "Human-readable description of the template's purpose"
1320                },
1321                "tags": {
1322                    "type": "array",
1323                    "items": { "type": "string" },
1324                    "description": "Tags for categorization and filtering"
1325                },
1326                "domain": {
1327                    "type": "string",
1328                    "description": "Storage scope: project (default), user, or org",
1329                    "enum": ["project", "user", "org"],
1330                    "default": "project"
1331                },
1332                "output_format": {
1333                    "type": "string",
1334                    "description": "Default output format: markdown (default), json, or xml",
1335                    "enum": ["markdown", "json", "xml"],
1336                    "default": "markdown"
1337                },
1338                "variables": {
1339                    "type": "array",
1340                    "description": "User-defined variable declarations",
1341                    "items": {
1342                        "type": "object",
1343                        "properties": {
1344                            "name": {
1345                                "type": "string",
1346                                "description": "Variable name (used as {{name}} in content)"
1347                            },
1348                            "description": {
1349                                "type": "string",
1350                                "description": "Description of what this variable represents"
1351                            },
1352                            "default": {
1353                                "type": "string",
1354                                "description": "Default value if not provided at render time"
1355                            },
1356                            "required": {
1357                                "type": "boolean",
1358                                "description": "Whether this variable must be provided (default: true)"
1359                            }
1360                        },
1361                        "required": ["name"]
1362                    }
1363                }
1364            },
1365            "required": ["name", "content"]
1366        }),
1367    }
1368}
1369
1370/// Defines the `context_template_list` tool.
1371pub fn context_template_list_tool() -> ToolDefinition {
1372    ToolDefinition {
1373        name: "context_template_list".to_string(),
1374        description: "List available context templates with optional filtering by domain, tags, or name pattern.".to_string(),
1375        input_schema: serde_json::json!({
1376            "type": "object",
1377            "properties": {
1378                "domain": {
1379                    "type": "string",
1380                    "description": "Filter by storage scope: project, user, or org",
1381                    "enum": ["project", "user", "org"]
1382                },
1383                "tags": {
1384                    "type": "array",
1385                    "items": { "type": "string" },
1386                    "description": "Filter by tags (must have ALL specified tags)"
1387                },
1388                "name_pattern": {
1389                    "type": "string",
1390                    "description": "Filter by name pattern (substring match)"
1391                },
1392                "limit": {
1393                    "type": "integer",
1394                    "description": "Maximum number of results (default: 20, max: 100)",
1395                    "minimum": 1,
1396                    "maximum": 100,
1397                    "default": 20
1398                }
1399            },
1400            "required": []
1401        }),
1402    }
1403}
1404
1405/// Defines the `context_template_get` tool.
1406pub fn context_template_get_tool() -> ToolDefinition {
1407    ToolDefinition {
1408        name: "context_template_get".to_string(),
1409        description: "Get a context template by name, optionally specifying version and domain."
1410            .to_string(),
1411        input_schema: serde_json::json!({
1412            "type": "object",
1413            "properties": {
1414                "name": {
1415                    "type": "string",
1416                    "description": "Template name to retrieve"
1417                },
1418                "version": {
1419                    "type": "integer",
1420                    "description": "Specific version to retrieve (default: latest)",
1421                    "minimum": 1
1422                },
1423                "domain": {
1424                    "type": "string",
1425                    "description": "Storage scope to search: project, user, or org",
1426                    "enum": ["project", "user", "org"]
1427                }
1428            },
1429            "required": ["name"]
1430        }),
1431    }
1432}
1433
1434/// Defines the `context_template_render` tool.
1435pub fn context_template_render_tool() -> ToolDefinition {
1436    ToolDefinition {
1437        name: "context_template_render".to_string(),
1438        description: "Render a context template with memories from a search query. Combines template rendering with memory recall for formatted output.".to_string(),
1439        input_schema: serde_json::json!({
1440            "type": "object",
1441            "properties": {
1442                "name": {
1443                    "type": "string",
1444                    "description": "Template name to render"
1445                },
1446                "version": {
1447                    "type": "integer",
1448                    "description": "Specific template version (default: latest)",
1449                    "minimum": 1
1450                },
1451                "query": {
1452                    "type": "string",
1453                    "description": "Search query to find memories for the template"
1454                },
1455                "namespaces": {
1456                    "type": "array",
1457                    "items": {
1458                        "type": "string",
1459                        "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
1460                    },
1461                    "description": "Filter memories by namespaces"
1462                },
1463                "limit": {
1464                    "type": "integer",
1465                    "description": "Maximum memories to include (default: 10)",
1466                    "minimum": 1,
1467                    "maximum": 50,
1468                    "default": 10
1469                },
1470                "format": {
1471                    "type": "string",
1472                    "description": "Override output format: markdown, json, or xml",
1473                    "enum": ["markdown", "json", "xml"]
1474                },
1475                "variables": {
1476                    "type": "object",
1477                    "description": "Custom variable values as key-value pairs",
1478                    "additionalProperties": { "type": "string" }
1479                }
1480            },
1481            "required": ["name"]
1482        }),
1483    }
1484}
1485
1486/// Defines the `context_template_delete` tool.
1487pub fn context_template_delete_tool() -> ToolDefinition {
1488    ToolDefinition {
1489        name: "context_template_delete".to_string(),
1490        description: "Delete a context template. Can delete a specific version or all versions."
1491            .to_string(),
1492        input_schema: serde_json::json!({
1493            "type": "object",
1494            "properties": {
1495                "name": {
1496                    "type": "string",
1497                    "description": "Template name to delete"
1498                },
1499                "version": {
1500                    "type": "integer",
1501                    "description": "Specific version to delete (omit to delete all versions)",
1502                    "minimum": 1
1503                },
1504                "domain": {
1505                    "type": "string",
1506                    "description": "Storage scope: project (default), user, or org",
1507                    "enum": ["project", "user", "org"],
1508                    "default": "project"
1509                }
1510            },
1511            "required": ["name", "domain"]
1512        }),
1513    }
1514}
1515
1516// ============================================================================
1517// Group Management Tools (Feature-gated: group-scope)
1518// ============================================================================
1519
1520/// Defines the `group_create` tool for creating new groups.
1521#[cfg(feature = "group-scope")]
1522pub fn group_create_tool() -> super::ToolDefinition {
1523    super::ToolDefinition {
1524        name: "subcog_group_create".to_string(),
1525        description:
1526            "Create a new group for shared memory access. You become the admin of the group."
1527                .to_string(),
1528        input_schema: serde_json::json!({
1529            "type": "object",
1530            "properties": {
1531                "name": {
1532                    "type": "string",
1533                    "description": "Group name (must be unique)"
1534                },
1535                "description": {
1536                    "type": "string",
1537                    "description": "Optional description of the group's purpose"
1538                }
1539            },
1540            "required": ["name"]
1541        }),
1542    }
1543}
1544
1545/// Defines the `group_list` tool for listing groups.
1546#[cfg(feature = "group-scope")]
1547pub fn group_list_tool() -> super::ToolDefinition {
1548    super::ToolDefinition {
1549        name: "subcog_group_list".to_string(),
1550        description: "List all groups you have access to, including your role in each.".to_string(),
1551        input_schema: serde_json::json!({
1552            "type": "object",
1553            "properties": {},
1554            "required": []
1555        }),
1556    }
1557}
1558
1559/// Defines the `group_get` tool for getting group details.
1560#[cfg(feature = "group-scope")]
1561pub fn group_get_tool() -> super::ToolDefinition {
1562    super::ToolDefinition {
1563        name: "subcog_group_get".to_string(),
1564        description: "Get details of a specific group, including members and their roles."
1565            .to_string(),
1566        input_schema: serde_json::json!({
1567            "type": "object",
1568            "properties": {
1569                "group_id": {
1570                    "type": "string",
1571                    "description": "The ID of the group to retrieve"
1572                }
1573            },
1574            "required": ["group_id"]
1575        }),
1576    }
1577}
1578
1579/// Defines the `group_add_member` tool for adding members to a group.
1580#[cfg(feature = "group-scope")]
1581pub fn group_add_member_tool() -> super::ToolDefinition {
1582    super::ToolDefinition {
1583        name: "subcog_group_add_member".to_string(),
1584        description:
1585            "Add a member to a group with a specified role. Requires admin role in the group."
1586                .to_string(),
1587        input_schema: serde_json::json!({
1588            "type": "object",
1589            "properties": {
1590                "group_id": {
1591                    "type": "string",
1592                    "description": "The ID of the group"
1593                },
1594                "user_id": {
1595                    "type": "string",
1596                    "description": "The user ID to add"
1597                },
1598                "role": {
1599                    "type": "string",
1600                    "description": "Role for the new member",
1601                    "enum": ["read", "write", "admin"],
1602                    "default": "read"
1603                }
1604            },
1605            "required": ["group_id", "user_id"]
1606        }),
1607    }
1608}
1609
1610/// Defines the `group_remove_member` tool for removing members from a group.
1611#[cfg(feature = "group-scope")]
1612pub fn group_remove_member_tool() -> super::ToolDefinition {
1613    super::ToolDefinition {
1614        name: "subcog_group_remove_member".to_string(),
1615        description: "Remove a member from a group. Requires admin role in the group.".to_string(),
1616        input_schema: serde_json::json!({
1617            "type": "object",
1618            "properties": {
1619                "group_id": {
1620                    "type": "string",
1621                    "description": "The ID of the group"
1622                },
1623                "user_id": {
1624                    "type": "string",
1625                    "description": "The user ID to remove"
1626                }
1627            },
1628            "required": ["group_id", "user_id"]
1629        }),
1630    }
1631}
1632
1633/// Defines the `group_update_role` tool for updating a member's role.
1634#[cfg(feature = "group-scope")]
1635pub fn group_update_role_tool() -> super::ToolDefinition {
1636    super::ToolDefinition {
1637        name: "subcog_group_update_role".to_string(),
1638        description: "Update a member's role in a group. Requires admin role in the group."
1639            .to_string(),
1640        input_schema: serde_json::json!({
1641            "type": "object",
1642            "properties": {
1643                "group_id": {
1644                    "type": "string",
1645                    "description": "The ID of the group"
1646                },
1647                "user_id": {
1648                    "type": "string",
1649                    "description": "The user ID to update"
1650                },
1651                "role": {
1652                    "type": "string",
1653                    "description": "New role for the member",
1654                    "enum": ["read", "write", "admin"]
1655                }
1656            },
1657            "required": ["group_id", "user_id", "role"]
1658        }),
1659    }
1660}
1661
1662/// Defines the `group_delete` tool for deleting a group.
1663#[cfg(feature = "group-scope")]
1664pub fn group_delete_tool() -> super::ToolDefinition {
1665    super::ToolDefinition {
1666        name: "subcog_group_delete".to_string(),
1667        description: "Delete a group. Requires admin role. Warning: This does not delete memories, but they will no longer be group-accessible.".to_string(),
1668        input_schema: serde_json::json!({
1669            "type": "object",
1670            "properties": {
1671                "group_id": {
1672                    "type": "string",
1673                    "description": "The ID of the group to delete"
1674                }
1675            },
1676            "required": ["group_id"]
1677        }),
1678    }
1679}
1680
1681/// Defines the consolidated `subcog_groups` tool.
1682///
1683/// Combines all group management operations into a single action-based tool.
1684#[cfg(feature = "group-scope")]
1685pub fn groups_tool() -> super::ToolDefinition {
1686    super::ToolDefinition {
1687        name: "subcog_groups".to_string(),
1688        description: "Manage groups for shared memory access. Actions: create, list, get, add_member, remove_member, update_role, delete.".to_string(),
1689        input_schema: serde_json::json!({
1690            "type": "object",
1691            "properties": {
1692                "action": {
1693                    "type": "string",
1694                    "description": "Operation to perform",
1695                    "enum": ["create", "list", "get", "add_member", "remove_member", "update_role", "delete"]
1696                },
1697                "group_id": {
1698                    "type": "string",
1699                    "description": "Group ID (required for get/add_member/remove_member/update_role/delete)"
1700                },
1701                "name": {
1702                    "type": "string",
1703                    "description": "Group name (required for create)"
1704                },
1705                "description": {
1706                    "type": "string",
1707                    "description": "Group description (for create)"
1708                },
1709                "user_id": {
1710                    "type": "string",
1711                    "description": "User ID to add/remove/update (for add_member/remove_member/update_role)"
1712                },
1713                "role": {
1714                    "type": "string",
1715                    "description": "Role for the member (for add_member/update_role)",
1716                    "enum": ["read", "write", "admin"],
1717                    "default": "read"
1718                }
1719            },
1720            "required": ["action"]
1721        }),
1722    }
1723}