Files
mcp-memory/server/src/tools.rs
T

1047 lines
43 KiB
Rust

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
/// Create new entities in the knowledge graph. Note: entity_type MUST ALWAYS be PascalCase (e.g. DatabaseTable, McpTool, File).
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct CreateEntitiesTool {
/// Array of entities to create.
pub entities: Vec<crate::models::Entity>,
}
/// Create new relations between entities in the knowledge graph.
/// Create new relations between entities in the knowledge graph (accepts 'from' or 'source', 'to' or 'target', and 'relation_type' or 'type').
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct CreateRelationsTool {
/// Array of relations to create. Each relation item MUST use 'from', 'to', and 'relation_type'.
pub relations: Vec<crate::models::Relation>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ObservationInput {
pub entity_name: String,
pub contents: Vec<String>,
}
/// Add new observations to existing entities in the knowledge graph.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AddObservationsTool {
/// Array of observations to add.
pub observations: Vec<ObservationInput>,
}
/// Delete entities from the knowledge graph.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct DeleteEntitiesTool {
/// Array of entity names to delete.
pub entity_names: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct DeleteObservationInput {
pub entity_name: String,
pub observations: Vec<String>,
}
/// Delete observations from existing entities.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct DeleteObservationsTool {
/// Array of observation deletions.
pub deletions: Vec<DeleteObservationInput>,
}
/// Delete relations between entities.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct DeleteRelationsTool {
/// Array of relations to delete.
pub relations: Vec<crate::models::Relation>,
}
/// Read the entire knowledge graph. WARNING: For large graphs, use search_nodes or pagination (limit, offset) to avoid context limits.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ReadGraphTool {
/// Optional namespace to restrict the read to.
pub namespace: Option<String>,
/// Optional token budget cap. Truncates graph outputs to fit within the specified token budget.
pub max_tokens: Option<usize>,
/// Optional maximum number of entities to return (pagination).
pub limit: Option<usize>,
/// Optional entity offset for pagination.
pub offset: Option<usize>,
}
/// Search specifically for Knowledge Graph entities and nodes by name or type.
/// Note: For searching across tasks, snippets, ADRs, error fixes, and graph entities simultaneously, use 'omni_search' instead.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct SearchNodesTool {
/// The search query.
pub query: String,
/// Optional namespace to restrict the search to.
pub namespace: Option<String>,
/// Limit the number of results to avoid context limit overflow. Defaults to 10.
pub limit: Option<usize>,
/// Include the full observations of the matched items. If false, returns only IDs and types (recommended for LLMs to prevent context bloat). Defaults to false.
pub include_body: Option<bool>,
}
/// Open and retrieve full details of specific nodes in the knowledge graph.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct OpenNodesTool {
/// Array of entity names to open.
pub names: Vec<String>,
}
/// Log a significant code change or refactor in the memory system.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct LogCodeChangeTool {
/// The path of the file that was changed.
pub file_path: String,
/// A description of the change.
pub description: String,
/// The associated git commit hash, if any.
pub git_commit: Option<String>,
/// The associated git branch, if any.
pub git_branch: Option<String>,
/// Optional symbol references (e.g. ['MemoryIndex', 'switchTab']) modified in this change.
pub symbol_references: Option<Vec<String>>,
/// Optional line range (e.g. 'L123-L145') modified in the target file.
pub line_range: Option<String>,
/// Optional repository name (e.g. 'mcp-memory', 'ai-pr-review').
pub repo_name: Option<String>,
/// Optional repository remote origin URL (e.g. 'git@bitbucket.org:org/repo.git' or 'svn://...').
pub repo_url: Option<String>,
/// Optional project namespace (defaults to repo_name or 'global').
pub namespace: Option<String>,
/// Optional change kind: 'added', 'modified', 'deleted', 'renamed'. Defaults to 'modified'.
pub change_kind: Option<String>,
/// Optional author or subagent attribution (e.g. 'user', 'MemoryLibrarian', SVN author).
pub author: Option<String>,
/// Optional conversation or session ID.
pub session_id: Option<String>,
/// Optional VCS system type: 'git', 'svn', 'hg', etc. Auto-detected if omitted.
pub vcs_type: Option<String>,
/// Optional VCS revision identifier (e.g. SVN 'r14829' or Git commit SHA).
pub revision: Option<String>,
/// Optional VCS branch (e.g. SVN 'trunk', 'branches/v1.0' or Git branch).
pub branch: Option<String>,
/// Optional repository root URL or path.
pub repository_root: Option<String>,
}
/// Query recently logged code changes.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct QueryRecentChangesTool {
/// Optional namespace to filter changes by project/workspace.
pub namespace: Option<String>,
/// Optional repository name to filter changes.
pub repo_name: Option<String>,
/// Optional VCS type to filter changes ('git', 'svn', etc.).
pub vcs_type: Option<String>,
/// Maximum number of records to return (defaults to 50).
pub limit: Option<usize>,
/// Optional offset for pagination.
pub offset: Option<usize>,
}
/// Generate a visual representation of the knowledge graph.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct VisualizeGraphTool {
/// Optional search query to filter the graph before visualization.
pub query: Option<String>,
/// Optional namespace to restrict the visualization to.
pub namespace: Option<String>,
}
/// Condense or summarize an entity's observations to reduce size.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct CondenseEntityTool {
/// The name of the entity to condense.
pub entity_name: String,
/// The condensed observations that will replace the existing ones.
pub summarized_observations: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum SubgraphFormat {
Json,
MarkdownTree,
}
/// Extract a multi-hop neighborhood subgraph around a specific root entity node as JSON or Markdown topology tree.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct GetSubgraphTool {
/// The root entity name to start the subgraph search from.
pub root_entity: Option<String>,
/// Legacy alias for root_entity.
pub root_node: Option<String>,
/// Maximum search depth (hops). Defaults to 2.
pub depth: Option<u32>,
/// Output format: 'json' (raw entities and relations) or 'markdown_tree' (compact topology tree). Defaults to 'json'.
pub format: Option<SubgraphFormat>,
/// Optional namespace filter.
pub namespace: Option<String>,
/// Target maximum token length for generated summary when format is 'markdown_tree'. Defaults to 1000.
pub max_tokens: Option<usize>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum CheckpointAction {
Create,
Restore,
List,
Delete,
}
/// Save, restore, list, or delete point-in-time memory state snapshot checkpoints.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ManageCheckpointTool {
/// Action to perform: 'create', 'restore', 'list', or 'delete'.
pub action: CheckpointAction,
/// Unique name or ID for the snapshot checkpoint.
pub name_or_id: Option<String>,
/// Optional description of why this checkpoint was created.
pub description: Option<String>,
/// Optional namespace filter.
pub namespace: Option<String>,
}
/// Merge two entities in the knowledge graph into one.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct MergeEntitiesTool {
/// The name of the entity to merge from (will be deleted).
pub source_entity: String,
/// The name of the entity to merge into.
pub target_entity: String,
}
/// Find orphaned entities (entities without any relations) in the graph.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct FindOrphansTool {}
/// Log a complex error and its fix for future reference.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct LogErrorFixTool {
/// The error signature or stack trace.
pub signature: String,
/// The solution applied to fix the error.
pub solution: String,
/// The associated git commit hash, if any.
pub git_commit: Option<String>,
/// The associated git branch, if any.
pub git_branch: Option<String>,
/// Optional symbol references (e.g. ['MemoryIndex', 'switchTab']) associated with the error.
pub symbol_references: Option<Vec<String>>,
/// Optional line range (e.g. 'L123-L145') associated with the error.
pub line_range: Option<String>,
}
/// Search historical error fixes using keyword query or stack trace vector similarity.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct SearchErrorFixesTool {
/// The search query string.
pub query: Option<String>,
/// Exact stack trace or error signature for vector cosine matching.
pub stack_trace: Option<String>,
/// Limit the number of results to avoid context limit overflow. Defaults to 5.
pub limit: Option<usize>,
/// Include the full solution details. If false, returns only error signatures. Defaults to false.
pub include_body: Option<bool>,
}
/// Add a summary of the current session.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AddSessionSummaryTool {
/// The summary content.
pub summary: String,
/// The namespace to add the summary to.
#[serde(default = "crate::models::default_namespace")]
pub namespace: String,
/// Optional conversation or session ID.
pub session_id: Option<String>,
/// Optional repository name.
pub repo_name: Option<String>,
/// Optional git branch.
pub git_branch: Option<String>,
/// Optional git commit hash.
pub git_commit: Option<String>,
/// Optional list of completed task IDs or task summaries in this session.
pub tasks_completed: Option<Vec<String>>,
/// Optional list of recommended next steps for incoming agents.
pub next_steps: Option<Vec<String>>,
}
/// Generate a standup report for a specific time window.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct GenerateStandupReportTool {
/// The namespace to generate the report for.
#[serde(default = "crate::models::default_namespace")]
pub namespace: String,
/// The number of hours to look back for activity.
pub hours_lookback: u64,
}
/// Search across all memory stores (Graph, Tasks, Snippets, ADRs, Error Fixes, Tech Debt) using Hybrid Reciprocal Rank Fusion (BM25 + Dense Vectors).
/// Highly recommended for discovery. Supports Lucene query syntax.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct OmniSearchTool {
/// The search query. Supports Lucene syntax (e.g., 'title:"auth" AND status:open').
pub query: String,
/// Optional namespace to restrict the search to.
pub namespace: Option<String>,
/// Limit the number of results per category to avoid context limit overflow. Defaults to 5.
pub limit: Option<usize>,
/// Include the full body/content of the matched items. If false, returns only IDs and titles (recommended for LLMs to prevent context bloat). Defaults to false.
pub include_body: Option<bool>,
/// Optional token budget cap. Dynamically caps and truncates search results to stay within max_tokens.
pub max_tokens: Option<usize>,
}
/// Get a health digest of the project.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct GetProjectHealthTool {
/// The namespace to get health for.
#[serde(default = "crate::models::default_namespace")]
pub namespace: String,
}
/// Traverse the knowledge graph to find a path between two entities.
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct QueryGraphPathTool {
/// The starting entity name.
pub start_node: String,
/// The ending entity name.
pub end_node: String,
/// Optional maximum depth to search.
pub max_depth: Option<u32>,
}
/// Define a strict checklist of acceptance criteria for a given task or feature before starting work.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct SetAcceptanceCriteriaTool {
pub task_title: String,
pub criteria: Vec<String>,
}
/// Mark a previously defined acceptance criteria as met by providing cryptographic-like proof.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct VerifyAcceptanceCriteriaTool {
pub task_id: String,
pub criteria: String,
pub proof: String,
}
/// Audit the knowledge graph to detect orphaned entities, compute name similarity for potential duplicate merges, and optionally auto-prune orphans and stale file/symbol tombstones (ADR-0111).
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct SweepGraphHealthTool {
/// Optional flag to automatically prune orphaned nodes with 0 relations. Defaults to false.
pub auto_prune_orphans: Option<bool>,
/// Minimum string similarity threshold (0.0 to 1.0) to report duplicate entity pairs. Defaults to 0.8.
pub similarity_threshold: Option<f32>,
/// Optional flag to prune stale entities whose file paths or symbols no longer exist on disk (ADR-0111). Defaults to false.
pub auto_prune_stale_files: Option<bool>,
}
/// Trace the causal provenance and historical lineage linking a task, ADR, git commit, code change, or error fix.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct QueryLineageTool {
/// The task ID, file path, symbol name, or git commit to query lineage for.
pub query: String,
}
/// Topological task resolver that returns unblocked, ready-to-run active tasks.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct GetNextActionableTasksTool {
/// Optional git branch filter.
pub git_branch: Option<String>,
/// Limit the number of actionable tasks returned. Defaults to 5.
pub limit: Option<usize>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum HypothesisAction {
Log,
Query,
}
/// Manage diagnostic hypotheses, tested evidence, and status during problem solving.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct HypothesesTool {
/// Action to perform: 'log' or 'query'.
pub action: HypothesisAction,
/// Optional task ID associated with this hypothesis or to filter hypotheses.
pub task_id: Option<String>,
/// The diagnostic hypothesis or potential root cause (required for action 'log').
pub hypothesis: Option<String>,
/// Status: 'unverified', 'verified', or 'rejected'. Defaults to 'unverified'.
pub status: Option<String>,
/// Evidence or test results supporting or disproving the hypothesis.
pub evidence: Option<String>,
/// Optional search query text (for action 'query').
pub query: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
use schemars::schema_for;
#[test]
fn test_schema_extraction_includes_descriptions() {
let schema = schema_for!(SetAcceptanceCriteriaTool);
let schema_json = serde_json::to_value(&schema).unwrap();
let desc = schema_json
.get("description")
.and_then(|d| d.as_str())
.unwrap_or("");
assert!(
desc.contains("Define a strict checklist of acceptance criteria"),
"Schema should include struct docstring as description"
);
let schema2 = schema_for!(LogCodeChangeTool);
let schema2_json = serde_json::to_value(&schema2).unwrap();
let props = schema2_json.get("properties").expect("Missing properties");
let file_path_prop = props.get("file_path").expect("Missing file_path property");
let field_desc = file_path_prop
.get("description")
.and_then(|d| d.as_str())
.unwrap_or("");
assert!(
field_desc.contains("The path of the file that was changed"),
"Schema should include field docstring as description"
);
}
}
/// Get the active worktree context, including branch name, modified files, and a truncated git diff.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct GetActiveWorktreeContextTool {}
/// Tail a specific log file in the background so it can be queried later.
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ProcessLogAction {
Watch,
Get,
Clear,
}
/// Monitor, tail, and manage process logs: watch a log file, tail recent output, or clear log files.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ProcessLogsTool {
/// Action to perform: 'watch', 'get', or 'clear'.
pub action: ProcessLogAction,
/// Path to the log file.
pub file_path: String,
/// Maximum number of lines to return for action 'get'. Defaults to 100.
pub max_lines: Option<usize>,
}
/// Read a file and return only its AST skeleton (Imports, Structs, Enums, Traits, Functions)
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ReadFileSkeletonTool {
pub file_path: String,
}
/// Replace a specific AST node in a file (robust structural editing). Use this instead of regex or line-based string replacement to prevent indentation bugs and matching failures.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ReplaceAstNodeTool {
pub file_path: String,
pub node_type: String, // e.g., "function_item", "impl_item"
pub node_name: String, // e.g., "execute"
pub new_content: String,
}
/// Semantic code search using local vector embeddings. Use this conceptual search instead of raw regex (grep) when trying to locate abstract logic or exploring new patterns.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct SemanticCodeSearchTool {
pub query: String,
pub directory: Option<String>,
}
/// Get a bird's-eye view of directory architecture. Use this when first exploring a new repository to get a summary of what each file is responsible for, instead of blindly reading files.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ReadDirectoryArchitectureTool {
pub directory: String,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum SubagentNamespaceAction {
Create,
Condense,
Purge,
}
/// Manage isolated memory namespaces for subagent sessions (create, condense/promote, or purge).
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ManageSubagentNamespaceTool {
/// Action to perform: 'create', 'condense', or 'purge'.
pub action: SubagentNamespaceAction,
/// Subagent namespace ID.
pub subagent_id: String,
/// For 'condense': whether to auto-purge the subagent namespace after promotion. Defaults to true.
pub purge_after_promotion: Option<bool>,
}
/// Find all source locations and AST chunks where a specific symbol (function, struct, method, type) is referenced or called.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct FindSymbolReferencesTool {
/// The symbol name (e.g. 'MemoryState', 'handle_search', 'AppError').
pub symbol: String,
/// Optional maximum number of reference locations to return. Defaults to 10.
pub limit: Option<usize>,
/// Optional workspace or directory path to scan. If omitted, falls back to active pinned files or current working directory.
#[serde(default, alias = "directory", alias = "path")]
pub workspace_dir: Option<String>,
}
/// Find all caller functions or methods that invoke a specified target function or method name.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct GetCallersTool {
/// The target function or method name (e.g. 'generate_embeddings_async', 'keyword_search').
pub function_name: String,
/// Optional maximum number of callers to return. Defaults to 10.
pub limit: Option<usize>,
/// Optional workspace or directory path to scan. If omitted, falls back to active pinned files or current working directory.
#[serde(default, alias = "directory", alias = "path")]
pub workspace_dir: Option<String>,
}
/// Query git commit history, diffs, and change ledger entries using keyword or semantic search.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct QueryGitDiffsTool {
/// Search query (e.g. 'deploy-server', 'shutdown', 'debounce', 'rename trick').
pub query: String,
/// Optional maximum number of commit diff entries to return. Defaults to 5.
pub limit: Option<usize>,
}
/// Promote a task observation or finding into a permanent Knowledge Graph entity.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct PromoteToEntityTool {
/// Note text or content to promote.
pub content: String,
/// Target entity name to create or merge into.
pub entity_name: String,
/// Entity type (e.g. 'Component', 'Decision', 'BugFix', 'Architecture').
pub entity_type: String,
/// Optional namespace. Defaults to 'default'.
#[serde(default = "crate::models::default_namespace")]
pub namespace: String,
}
/// Analyze the potential downstream breaking impact of modifying a function, struct, or file across AST callers and Knowledge Graph relations.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AnalyzeImpactTool {
/// Target function, struct, or symbol name (e.g. 'MemoryState', 'execute', 'AppError').
pub target_symbol: String,
/// Optional file path.
pub file_path: Option<String>,
}
/// Get a consolidated 1-page executive summary of current active branch, active task, open tech debt, and diagnostic hypotheses in 1 turn.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct GetPreflightContextTool {
/// Optional namespace. Defaults to 'default'.
#[serde(default = "crate::models::default_namespace")]
pub namespace: String,
/// Optional git branch to filter context for.
pub git_branch: Option<String>,
}
/// Inspect Knowledge Graph entities, observations, and tech debt symbol/line references against current files on disk and AST, flagging and healing stale or broken pointers.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ResolveStaleSymbolsTool {
/// Optional entity or file path to check. If omitted, checks all graph entities and tech debts.
pub target: Option<String>,
/// Whether to automatically update or remove broken references. Defaults to true.
pub auto_heal: Option<bool>,
}
/// Generate a compact, LLM-optimized Markdown topology or summary of a graph component capped within a strict token budget.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct SummarizeSubgraphTool {
/// The root entity name to center the summary on (e.g. 'MemoryState', 'ServerRouter').
pub root_entity: String,
/// Search depth from root entity. Defaults to 2.
pub depth: Option<usize>,
/// Target maximum token length for the generated summary. Defaults to 1000.
pub max_tokens: Option<usize>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum AgentSignalAction {
Broadcast,
Query,
}
/// Real-time inter-agent communication bus: broadcast signals or query active signals from peer subagents.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AgentSignalsTool {
/// Action to perform: 'broadcast' or 'query'.
pub action: AgentSignalAction,
/// Sender agent ID or role (e.g. 'PrePushAuditor', 'MemoryLibrarian'). Required for broadcast; optional filter for query.
pub sender: Option<String>,
/// Signal type or event category (e.g. 'AUDIT_PASSED', 'REPRODUCER_READY', 'TESTS_FAILED'). Required for broadcast; optional filter for query.
pub signal_type: Option<String>,
/// JSON or text payload containing event details or artifact URIs (required for action 'broadcast').
pub payload: Option<String>,
/// Optional Time-To-Live in seconds for the signal. Defaults to 3600 (1 hour).
pub ttl_seconds: Option<u64>,
/// Optional limit on returned signals (for action 'query'). Defaults to 20.
pub limit: Option<usize>,
}
/// Trigger an automated context checkpoint, summarizing active tasks, hypotheses, recent commits, and open tech debt into a permanent HandoffMemo.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AutoSessionCheckpointTool {
/// Author or agent ID creating the checkpoint. Defaults to 'AutoCheckpoint'.
pub author: Option<String>,
/// Optional namespace. Defaults to 'default'.
#[serde(default = "crate::models::default_namespace")]
pub namespace: String,
}
// Consolidated Smart Management Tools
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum HandoffMemoAction {
#[serde(alias = "leave", alias = "LEAVE", alias = "Leave")]
Leave,
#[serde(alias = "read", alias = "READ", alias = "Read")]
Read,
#[serde(alias = "clear", alias = "CLEAR", alias = "Clear")]
Clear,
}
/// Persistent handoff memos for passing session context to future agents.
/// Actions:
/// - 'leave': Post a handoff memo. Required: content. Optional: namespace.
/// - 'read': Inspect active memos. Optional: namespace.
/// - 'clear': Clear memos. Optional: namespace, ids.
///
/// Next steps on error: Check parameter requirements for 'leave' or 'clear' actions.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct HandoffMemosTool {
/// Action to perform: 'leave', 'read', or 'clear'.
pub action: HandoffMemoAction,
/// Content of the handoff memo (required for 'leave').
pub content: Option<String>,
/// Optional namespace filter or assignment.
pub namespace: Option<String>,
/// Array of memo IDs to clear (required for 'clear').
pub ids: Option<Vec<String>>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TaskAction {
#[serde(alias = "add", alias = "ADD", alias = "Add")]
Add,
#[serde(alias = "update", alias = "UPDATE", alias = "Update")]
Update,
#[serde(alias = "delete", alias = "DELETE", alias = "Delete")]
Delete,
#[serde(alias = "list", alias = "LIST", alias = "List")]
List,
#[serde(
alias = "set_criteria",
alias = "setCriteria",
alias = "SET_CRITERIA",
alias = "SetCriteria"
)]
SetCriteria,
#[serde(alias = "verify", alias = "VERIFY", alias = "Verify")]
Verify,
}
/// Action-oriented task tracking system (add, update, delete, list, set_criteria, verify).
/// Actions:
/// - 'add': Create task. Required: title. Optional: description, git_branch, parent_id, dependencies.
/// - 'update': Update task status. Required: id, status ('pending'|'completed'|'cancelled').
/// - 'delete': Delete task & subtasks. Required: id.
/// - 'list': List active tasks. Optional: git_branch, summary_level ('compact'|'detailed'|'full'), max_tokens.
/// - 'set_criteria': Set acceptance criteria. Required: id, criteria (array of strings).
/// - 'verify': Verify criteria met. Required: id.
///
/// Next steps on error: Check required parameters or call list to verify task IDs.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct TasksTool {
/// Action to perform: 'add', 'update', 'delete', 'list', 'set_criteria', or 'verify'.
pub action: TaskAction,
/// Task ID (required for 'update', 'delete', 'set_criteria', 'verify').
#[serde(alias = "task_id", alias = "taskId")]
pub id: Option<String>,
/// Task title (required for 'add').
#[serde(alias = "name")]
pub title: Option<String>,
/// Task description (optional for 'add').
#[serde(alias = "desc")]
pub description: Option<String>,
/// New status: 'pending', 'completed', or 'cancelled' (for 'update').
pub status: Option<String>,
/// Parent task ID (optional for 'add').
#[serde(alias = "parentId", alias = "parent")]
pub parent_id: Option<String>,
/// List of dependency task IDs (optional for 'add').
#[serde(alias = "deps")]
pub dependencies: Option<Vec<String>>,
/// Git branch filter or assignment.
#[serde(alias = "branch")]
pub git_branch: Option<String>,
/// Acceptance criteria (required for 'set_criteria').
#[serde(alias = "acceptance_criteria", alias = "acceptanceCriteria")]
pub criteria: Option<Vec<String>>,
/// Verification proof or details (optional for 'verify').
pub proof: Option<String>,
/// Summary level: 'compact', 'detailed', or 'full' (for 'list').
pub summary_level: Option<String>,
/// Maximum tokens budget cap (for 'list').
pub max_tokens: Option<usize>,
/// Optional namespace filter or assignment (defaults to 'default').
pub namespace: Option<String>,
/// Optional repository name.
pub repo_name: Option<String>,
/// Optional task priority: 'low', 'medium', 'high', 'urgent'.
pub priority: Option<String>,
/// Optional assigned subagent role or identifier.
pub assigned_agent: Option<String>,
/// Optional verification command to validate criteria completion.
/// Optional pagination offset for 'list'.
pub offset: Option<usize>,
pub verification_command: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum MilestoneAction {
#[serde(alias = "add", alias = "ADD", alias = "Add")]
Add,
#[serde(alias = "update", alias = "UPDATE", alias = "Update")]
Update,
#[serde(alias = "list", alias = "LIST", alias = "List")]
List,
}
/// Project milestone management (add, update, list).
/// Actions:
/// - 'add': Create milestone. Required: title. Optional: namespace.
/// - 'update': Update milestone status. Required: id, status.
/// - 'list': List milestones. Optional: namespace.
///
/// Next steps on error: Provide required title for 'add' or id/status for 'update'.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct MilestonesTool {
/// Action to perform: 'add', 'update', or 'list'.
pub action: MilestoneAction,
/// Milestone ID (required for 'update').
#[serde(alias = "milestone_id", alias = "milestoneId")]
pub id: Option<String>,
/// Milestone title (required for 'add').
#[serde(alias = "name")]
pub title: Option<String>,
/// New status (for 'update').
pub status: Option<String>,
/// Optional namespace filter or assignment.
pub namespace: Option<String>,
/// Optional target completion date.
pub target_date: Option<String>,
/// Optional description of milestone scope.
pub description: Option<String>,
/// Optional deliverables or task checklist.
pub deliverables: Option<Vec<String>>,
/// Optional list of task IDs associated with this milestone.
#[serde(default)]
pub task_ids: Option<Vec<String>>,
/// Optional repository name.
pub repo_name: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum SnippetAction {
#[serde(alias = "store", alias = "STORE", alias = "Store")]
Store,
#[serde(alias = "search", alias = "SEARCH", alias = "Search")]
Search,
#[serde(alias = "delete", alias = "DELETE", alias = "Delete")]
Delete,
#[serde(alias = "tag", alias = "TAG", alias = "Tag")]
Tag,
}
/// Syntactically preserved reusable code snippets vault (store, search, delete, tag).
/// Actions:
/// - 'store': Store snippet. Required: query (or id) as snippet name. Optional: language, code, description, tags.
/// - 'search': Search snippets. Optional: query, tags, hybrid (boolean for BM25+vector search).
/// - 'delete': Delete snippet. Required: id (or query) as snippet name.
/// - 'tag': Tag snippet. Required: id (or query), tags (array of strings).
///
/// Next steps on error: Ensure snippet name/query or id is provided.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct SnippetsTool {
/// Action to perform: 'store', 'search', 'delete', or 'tag'.
pub action: SnippetAction,
/// Snippet ID or name (required for 'delete', 'tag').
pub id: Option<String>,
/// Search query or snippet name (required for 'store').
pub query: Option<String>,
/// Snippet name alias (for 'store', 'delete', 'tag').
pub name: Option<String>,
/// Snippet language (for 'store').
pub language: Option<String>,
/// Code content (for 'store').
pub code: Option<String>,
/// Snippet description (for 'store').
pub description: Option<String>,
/// Classification tags (for 'store', 'search', 'tag').
pub tags: Option<Vec<String>>,
/// Enable hybrid lexical + semantic vector ranking (for 'search').
pub hybrid: Option<bool>,
/// Optional project namespace.
pub namespace: Option<String>,
/// Optional repository name.
pub repo_name: Option<String>,
/// Optional origin file path where the snippet was extracted from.
pub origin_file: Option<String>,
/// Optional line range in origin file (e.g. 'L10-L45').
pub line_range: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq, Clone)]
#[serde(rename_all = "snake_case")]
pub enum DecisionAction {
#[serde(alias = "log", alias = "LOG", alias = "Log")]
Log,
#[serde(alias = "query", alias = "QUERY", alias = "Query")]
Query,
#[serde(alias = "delete", alias = "DELETE", alias = "Delete")]
Delete,
#[serde(alias = "update", alias = "UPDATE", alias = "Update")]
Update,
}
/// Architectural Decision Records (ADRs) log (log, query, update, delete).
/// Actions:
/// - 'log': Record ADR. Required: title. Optional: status, context, decision, consequences, namespace.
/// - 'query': Search ADRs. Optional: query, namespace.
/// - 'update': Update ADR status or implementation info. Required: id. Optional: status, git_commit, git_branch, task_id, context, decision, consequences, title.
/// - 'delete': Remove ADR. Required: id.
///
/// Next steps on error: Provide title for 'log' or id for 'update'/'delete'.
#[derive(Deserialize, Serialize, JsonSchema, Debug, Clone)]
pub struct DecisionsTool {
/// Action to perform: 'log', 'query', or 'delete'.
pub action: DecisionAction,
/// ADR ID (required for 'delete').
pub id: Option<String>,
/// ADR title (required for 'log').
pub title: Option<String>,
/// ADR status (for 'log').
pub status: Option<String>,
/// Context & problem statement (for 'log').
pub context: Option<String>,
/// Decision made (for 'log').
pub decision: Option<String>,
/// Consequences & tradeoffs (for 'log').
#[serde(alias = "consequence")]
pub consequences: Option<String>,
/// Search query string (for 'query').
pub query: Option<String>,
/// Optional namespace.
pub namespace: Option<String>,
/// Optional repository name.
pub repo_name: Option<String>,
/// Optional author or architect behind the decision.
pub author: Option<String>,
/// Optional affected system components or crates.
pub affected_components: Option<Vec<String>>,
/// Optional alternative designs or libraries considered.
pub alternatives_considered: Option<Vec<String>>,
/// Optional superseded ADR ID.
pub supersedes: Option<String>,
/// Limit the number of query results. Defaults to 20.
pub limit: Option<usize>,
/// Include the full body of the matched decisions. Defaults to true.
pub include_body: Option<bool>,
/// Optional Git commit where decision was implemented.
pub git_commit: Option<String>,
/// Optional Git branch where decision was implemented.
pub git_branch: Option<String>,
/// Optional task ID linked to this decision.
pub task_id: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TechDebtAction {
#[serde(alias = "log", alias = "LOG", alias = "Log")]
Log,
#[serde(alias = "resolve", alias = "RESOLVE", alias = "Resolve")]
Resolve,
#[serde(alias = "list", alias = "LIST", alias = "List")]
List,
}
/// Technical debt backlog management (log, resolve, list).
/// Actions:
/// - 'log': Record technical debt. Required: description. Optional: ideal_solution, git_commit, git_branch, symbol_references, line_range, namespace.
/// - 'resolve': Mark tech debt resolved. Required: id.
/// - 'list': List tech debt items. Optional: include_resolved, namespace.
///
/// Next steps on error: Provide description for 'log' or valid ID for 'resolve'.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct TechDebtTool {
/// Action to perform: 'log', 'resolve', or 'list'.
pub action: TechDebtAction,
/// Tech debt ID (required for 'resolve').
#[serde(alias = "tech_debt_id", alias = "debt_id")]
pub id: Option<String>,
/// Tech debt description (required for 'log').
#[serde(alias = "desc")]
pub description: Option<String>,
/// Optional title or summary of tech debt.
pub title: Option<String>,
/// Ideal solution (optional for 'log').
#[serde(alias = "solution", alias = "fix")]
pub ideal_solution: Option<String>,
/// Include resolved tech debt items (for 'list').
pub include_resolved: Option<bool>,
/// Associated git commit hash.
#[serde(alias = "commit")]
pub git_commit: Option<String>,
/// Associated git branch.
#[serde(alias = "branch")]
pub git_branch: Option<String>,
/// Symbol references associated with the tech debt.
pub symbol_references: Option<Vec<String>>,
/// Line range associated with the tech debt.
pub line_range: Option<String>,
/// Optional namespace.
pub namespace: Option<String>,
/// Optional debt severity: 'low', 'medium', 'high', 'critical'.
pub severity: Option<String>,
/// Optional repository name.
pub repo_name: Option<String>,
/// Optional file path where debt exists.
pub file_path: Option<String>,
/// Optional workaround currently in place.
pub workaround: Option<String>,
/// Optional effort estimate to fix.
pub effort_estimate: Option<String>,
/// Summary level for list action: 'compact', 'detailed', or 'full'.
pub summary_level: Option<String>,
/// Optional token budget cap for list output.
pub max_tokens: Option<usize>,
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum EnvAction {
#[serde(
alias = "update_fingerprint",
alias = "updateFingerprint",
alias = "UPDATE_FINGERPRINT",
alias = "UpdateFingerprint"
)]
UpdateFingerprint,
#[serde(
alias = "read_fingerprint",
alias = "readFingerprint",
alias = "READ_FINGERPRINT",
alias = "ReadFingerprint"
)]
ReadFingerprint,
#[serde(
alias = "log_requirement",
alias = "logRequirement",
alias = "LOG_REQUIREMENT",
alias = "LogRequirement"
)]
LogRequirement,
#[serde(alias = "register", alias = "REGISTER", alias = "Register")]
Register,
#[serde(
alias = "get_details",
alias = "getDetails",
alias = "GET_DETAILS",
alias = "GetDetails"
)]
GetDetails,
}
/// Environment requirements, tool fingerprints & infrastructure management.
/// Actions:
/// - 'update_fingerprint': Update tool versions. Optional: tool_versions map, namespace.
/// - 'read_fingerprint': Read current environment fingerprint. Optional: namespace.
/// - 'log_requirement': Log environment variable requirement. Required: key. Optional: description, is_secret, namespace.
/// - 'register': Register remote target environment. Required: name. Optional: url, description, requires_vpn, namespace.
/// - 'get_details': Get full environment details. Optional: namespace.
///
/// Next steps on error: Provide key for 'log_requirement' or name for 'register'.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct EnvironmentTool {
/// Action to perform: 'update_fingerprint', 'read_fingerprint', 'log_requirement', 'register', or 'get_details'.
pub action: EnvAction,
/// Map of tool names to versions (for 'update_fingerprint').
pub tool_versions: Option<std::collections::HashMap<String, String>>,
/// Env variable key (required for 'log_requirement').
pub key: Option<String>,
/// Description (for 'log_requirement', 'register').
pub description: Option<String>,
/// Secret flag (for 'log_requirement').
pub is_secret: Option<bool>,
/// Environment name (required for 'register').
pub name: Option<String>,
/// Environment URL (for 'register').
pub url: Option<String>,
/// VPN required flag (for 'register').
pub requires_vpn: Option<bool>,
/// Optional namespace.
pub namespace: Option<String>,
/// Optional operating system name (e.g. 'windows', 'linux', 'darwin').
pub os: Option<String>,
/// Optional shell name (e.g. 'pwsh', 'bash', 'zsh', 'cmd').
pub shell: Option<String>,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ClipboardAction {
#[serde(
alias = "image",
alias = "IMAGE",
alias = "Image",
alias = "screenshot",
alias = "SCREENSHOT"
)]
Image,
#[serde(alias = "text", alias = "TEXT", alias = "Text")]
Text,
#[serde(alias = "history", alias = "HISTORY", alias = "History")]
History,
#[serde(alias = "clear", alias = "CLEAR", alias = "Clear")]
Clear,
#[serde(alias = "read", alias = "READ", alias = "Read")]
Read,
#[serde(alias = "write", alias = "WRITE", alias = "Write")]
Write,
}
/// Smart OS Clipboard management with overwrite-immune screenshot caching and OCR.
/// Actions:
/// - 'image': Get latest screenshot image path (Windows + WSL) and extracted verbatim OCR text.
/// Returns cached screenshot even if text was copied afterwards!
/// - 'text': Get latest clipboard text (or normalized Markdown if HTML was copied).
/// - 'history': View recent clipboard history ring buffer (images and text with timestamps).
/// - 'clear': Clear OS clipboard and memory cache.
/// - 'read': Read current clipboard contents (legacy alias).
/// - 'write': Write content to OS clipboard. Optional: text, html, files, image_path.
///
/// Triggers: Call 'image' immediately when user says "look at image in clipboard", "see screenshot",
/// "look at clipboard", "what I copied", or shares terminal error captures.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct ClipboardTool {
/// Action to perform: 'image', 'text', 'history', 'clear', 'read', or 'write'.
pub action: ClipboardAction,
/// Plain text content (for 'write').
pub text: Option<String>,
/// HTML content (for 'write').
pub html: Option<String>,
/// File paths for Windows File Drop (for 'write').
pub files: Option<Vec<String>>,
/// Image path (for 'write').
pub image_path: Option<String>,
}