docs: update human and LLM docs and enhance tool/list schemas with actionable next steps

This commit is contained in:
Riz Ashraf committed 2026-10-05 11:22:55 +01:00
1 parent 961abb01e7
commit 4b307b55b9
12 files changed
+307 -336

No files matched your search

+2 -2
View File
@@ -190,7 +190,7 @@ impl McpTool for EnvironmentHandler {
}
EnvAction::LogRequirement => {
let key = req.key.ok_or_else(|| {
crate::error::AppError::Internal("key is required for 'log_requirement' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'key' for action 'log_requirement'. Next step: Provide environment variable 'key' string in request and retry.".to_string())
})?;
let desc = req.description.unwrap_or_default();
let secret = req.is_secret.unwrap_or(false);
@@ -198,7 +198,7 @@ impl McpTool for EnvironmentHandler {
}
EnvAction::Register => {
let name = req.name.ok_or_else(|| {
crate::error::AppError::Internal("name is required for 'register' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'name' for action 'register'. Next step: Provide environment 'name' string in request and retry.".to_string())
})?;
let url = req.url.unwrap_or_default();
let desc = req.description.unwrap_or_default();
+4 -4
View File
@@ -545,7 +545,7 @@ impl McpTool for DecisionsHandler {
match req.action {
DecisionAction::Log => {
let title = req.title.ok_or_else(|| {
crate::error::AppError::Internal("title is required for 'log' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'title' for action 'log'. Next step: Provide ADR 'title' string in request and retry.".to_string())
})?;
let status = req.status.unwrap_or_else(|| "accepted".to_string());
let context = req.context.unwrap_or_default();
@@ -568,7 +568,7 @@ impl McpTool for DecisionsHandler {
}
DecisionAction::Delete => {
let id = req.id.ok_or_else(|| {
crate::error::AppError::Internal("id is required for 'delete' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' for action 'delete'. Next step: Provide ADR 'id' string in request and retry.".to_string())
})?;
DeleteDecisionHandler.execute(serde_json::json!({"id": id}), state).await
}
@@ -597,7 +597,7 @@ impl McpTool for TechDebtHandler {
match req.action {
TechDebtAction::Log => {
let desc = req.description.ok_or_else(|| {
crate::error::AppError::Internal("description is required for 'log' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'description' for action 'log'. Next step: Provide tech debt 'description' in request and retry.".to_string())
})?;
let ideal = req.ideal_solution.unwrap_or_default();
LogTechDebtHandler.execute(
@@ -615,7 +615,7 @@ impl McpTool for TechDebtHandler {
}
TechDebtAction::Resolve => {
let id = req.id.ok_or_else(|| {
crate::error::AppError::Internal("id is required for 'resolve' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' for action 'resolve'. Next step: Provide tech debt 'id' string in request and retry.".to_string())
})?;
ResolveTechDebtHandler.execute(serde_json::json!({"id": id}), state).await
}
+4 -4
View File
@@ -27,7 +27,7 @@ impl McpTool for StickyNotesHandler {
match req.action {
StickyNoteAction::Add => {
let content = req.content.ok_or_else(|| {
crate::error::AppError::Internal("content is required for 'add' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'content' for action 'add'. Next step: Provide non-empty 'content' string in request and retry.".to_string())
})?;
let now = crate::handlers::utils::now_secs();
let expires_at = if let Some(ttl) = req.ttl_seconds {
@@ -64,7 +64,7 @@ impl McpTool for StickyNotesHandler {
}
StickyNoteAction::Delete => {
let idx = req.index.ok_or_else(|| {
crate::error::AppError::Internal("index is required for 'delete' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'index' for action 'delete'. Next step: Provide 1-based sticky note 'index' integer in request and retry.".to_string())
})?;
let mut success = false;
state.code.sticky.modify(|notes| {
@@ -77,7 +77,7 @@ impl McpTool for StickyNotesHandler {
Ok("Sticky note deleted.".to_string())
} else {
Err(crate::error::AppError::Internal(
"Invalid sticky note index.".to_string(),
"Invalid sticky note index. Next step: Call sticky_notes with action='read' to view active notes and valid 1-based indices, then retry.".to_string(),
))
}
}
@@ -236,7 +236,7 @@ impl McpTool for HandoffMemosHandler {
match req.action {
HandoffMemoAction::Leave => {
let content = req.content.ok_or_else(|| {
crate::error::AppError::Internal("content is required for 'leave' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'content' for action 'leave'. Next step: Provide non-empty 'content' string in request and retry.".to_string())
})?;
let ns = req.namespace.unwrap_or_else(|| crate::models::default_namespace());
state.telemetry.handoff_memos.modify(|memos| {
+10 -10
View File
@@ -532,7 +532,7 @@ impl McpTool for TasksHandler {
match req.action {
TaskAction::Add => {
let title = req.title.ok_or_else(|| {
crate::error::AppError::Internal("title is required for 'add' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'title' for action 'add'. Next step: Provide non-empty 'title' string in request and retry.".to_string())
})?;
let description = req.description.unwrap_or_default();
let add_args = serde_json::json!({
@@ -546,10 +546,10 @@ impl McpTool for TasksHandler {
}
TaskAction::Update => {
let id = req.id.ok_or_else(|| {
crate::error::AppError::Internal("id is required for 'update' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' for action 'update'. Next step: Provide task 'id' string in request and retry.".to_string())
})?;
let status = req.status.ok_or_else(|| {
crate::error::AppError::Internal("status is required for 'update' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'status' for action 'update'. Next step: Provide valid 'status' ('pending', 'completed', or 'cancelled') in request and retry.".to_string())
})?;
let update_args = serde_json::json!({
"id": id,
@@ -559,7 +559,7 @@ impl McpTool for TasksHandler {
}
TaskAction::Delete => {
let id = req.id.ok_or_else(|| {
crate::error::AppError::Internal("id is required for 'delete' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' for action 'delete'. Next step: Provide task 'id' string in request and retry.".to_string())
})?;
let del_args = serde_json::json!({
"id": id,
@@ -576,10 +576,10 @@ impl McpTool for TasksHandler {
}
TaskAction::SetCriteria => {
let id = req.id.ok_or_else(|| {
crate::error::AppError::Internal("id is required for 'set_criteria' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' for action 'set_criteria'. Next step: Provide task 'id' string in request and retry.".to_string())
})?;
let criteria = req.criteria.ok_or_else(|| {
crate::error::AppError::Internal("criteria array is required for 'set_criteria' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'criteria' for action 'set_criteria'. Next step: Provide array of acceptance criteria descriptions in request and retry.".to_string())
})?;
let set_args = serde_json::json!({
"id": id,
@@ -589,7 +589,7 @@ impl McpTool for TasksHandler {
}
TaskAction::Verify => {
let id = req.id.ok_or_else(|| {
crate::error::AppError::Internal("id is required for 'verify' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' for action 'verify'. Next step: Provide task 'id' string in request and retry.".to_string())
})?;
let verify_args = serde_json::json!({
"id": id,
@@ -620,7 +620,7 @@ impl McpTool for MilestonesHandler {
match req.action {
MilestoneAction::Add => {
let title = req.title.ok_or_else(|| {
crate::error::AppError::Internal("title is required for 'add' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'title' for action 'add'. Next step: Provide non-empty 'title' string in request and retry.".to_string())
})?;
let add_args = serde_json::json!({
"title": title,
@@ -630,10 +630,10 @@ impl McpTool for MilestonesHandler {
}
MilestoneAction::Update => {
let id = req.id.ok_or_else(|| {
crate::error::AppError::Internal("id is required for 'update' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' for action 'update'. Next step: Provide milestone 'id' string in request and retry.".to_string())
})?;
let status = req.status.ok_or_else(|| {
crate::error::AppError::Internal("status is required for 'update' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'status' for action 'update'. Next step: Provide milestone 'status' in request and retry.".to_string())
})?;
let update_args = serde_json::json!({
"id": id,
+11 -11
View File
@@ -496,13 +496,13 @@ impl McpTool for PinnedFilesHandler {
match req.action {
PinnedFileAction::Pin => {
let path = req.path.ok_or_else(|| {
crate::error::AppError::Internal("path is required for 'pin' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'path' for action 'pin'. Next step: Provide absolute or relative file 'path' in request and retry.".to_string())
})?;
PinFileHandler.execute(serde_json::json!({"file_path": path, "namespace": ns}), state).await
}
PinnedFileAction::Unpin => {
let path = req.path.ok_or_else(|| {
crate::error::AppError::Internal("path is required for 'unpin' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'path' for action 'unpin'. Next step: Provide file 'path' in request and retry.".to_string())
})?;
UnpinFileHandler.execute(serde_json::json!({"file_path": path, "namespace": ns}), state).await
}
@@ -534,7 +534,7 @@ impl McpTool for ContextWorkspacesHandler {
match req.action {
ContextWorkspaceAction::Save => {
let name = req.name.ok_or_else(|| {
crate::error::AppError::Internal("name is required for 'save' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'name' for action 'save'. Next step: Provide workspace 'name' string in request and retry.".to_string())
})?;
let pinned_files = req.pinned_files.unwrap_or_default();
let active_task_ids = req.active_task_ids.unwrap_or_default();
@@ -550,7 +550,7 @@ impl McpTool for ContextWorkspacesHandler {
}
ContextWorkspaceAction::Load => {
let name = req.name.ok_or_else(|| {
crate::error::AppError::Internal("name is required for 'load' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'name' for action 'load'. Next step: Provide workspace 'name' string in request and retry.".to_string())
})?;
LoadContextWorkspaceHandler.execute(serde_json::json!({"name": name, "namespace": ns}), state).await
}
@@ -559,16 +559,16 @@ impl McpTool for ContextWorkspacesHandler {
}
ContextWorkspaceAction::Delete => {
let name = req.name.ok_or_else(|| {
crate::error::AppError::Internal("name is required for 'delete' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'name' for action 'delete'. Next step: Provide workspace 'name' string in request and retry.".to_string())
})?;
DeleteContextWorkspaceHandler.execute(serde_json::json!({"name": name, "namespace": ns}), state).await
}
ContextWorkspaceAction::Diff => {
let name = req.name.ok_or_else(|| {
crate::error::AppError::Internal("name is required for 'diff' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'name' for action 'diff'. Next step: Provide primary workspace 'name' in request and retry.".to_string())
})?;
let other = req.other_name.ok_or_else(|| {
crate::error::AppError::Internal("other_name is required for 'diff' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'other_name' for action 'diff'. Next step: Provide secondary workspace 'other_name' in request and retry.".to_string())
})?;
DiffContextWorkspacesHandler.execute(serde_json::json!({"workspace_a": name, "workspace_b": other, "namespace": ns}), state).await
}
@@ -597,7 +597,7 @@ impl McpTool for PrChecklistHandler {
match req.action {
PrChecklistAction::Add => {
let desc = req.description.ok_or_else(|| {
crate::error::AppError::Internal("description is required for 'add' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'description' for action 'add'. Next step: Provide checklist item 'description' string in request and retry.".to_string())
})?;
AddPrChecklistItemHandler.execute(serde_json::json!({"description": desc, "namespace": ns}), state).await
}
@@ -631,7 +631,7 @@ impl McpTool for SnippetsHandler {
match req.action {
SnippetAction::Store => {
let name = req.query.or(req.id).ok_or_else(|| {
crate::error::AppError::Internal("name is required for 'store' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'query' or 'id' as snippet name for action 'store'. Next step: Provide snippet name in 'query' field and retry.".to_string())
})?;
let lang = req.language.unwrap_or_else(|| "text".to_string());
let code = req.code.unwrap_or_default();
@@ -657,13 +657,13 @@ impl McpTool for SnippetsHandler {
}
SnippetAction::Delete => {
let id = req.id.or(req.query).ok_or_else(|| {
crate::error::AppError::Internal("id/name is required for 'delete' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' or 'query' for action 'delete'. Next step: Provide snippet ID/name in request and retry.".to_string())
})?;
DeleteSnippetHandler.execute(serde_json::json!({"name": id}), state).await
}
SnippetAction::Tag => {
let id = req.id.or(req.query).ok_or_else(|| {
crate::error::AppError::Internal("id/name is required for 'tag' action".to_string())
crate::error::AppError::Internal("Missing required parameter 'id' or 'query' for action 'tag'. Next step: Provide snippet ID/name and 'tags' array in request and retry.".to_string())
})?;
let tags = req.tags.unwrap_or_default();
TagSnippetHandler.execute(serde_json::json!({"name": id, "tags": tags}), state).await