Skip to main content

task_graph_mcp/tools/
workflows.rs

1//! Workflow discovery tool for listing available workflows before connecting.
2
3use super::make_tool;
4use crate::config::workflows::WorkflowsConfig;
5use anyhow::Result;
6use rmcp::model::Tool;
7use serde_json::{Value, json};
8
9/// Get workflow discovery tools.
10pub fn get_tools() -> Vec<Tool> {
11    vec![make_tool(
12        "list_workflows",
13        "List all available workflows. Returns name + description for each workflow. \
14         Call BEFORE connecting to discover which workflows exist. \
15         Use the workflow name with the `connect` tool's `workflow` parameter.",
16        json!({}),
17        vec![],
18    )]
19}
20
21/// List available workflows from the named_workflows cache.
22pub fn list_workflows(workflows: &WorkflowsConfig) -> Result<Value> {
23    let mut entries: Vec<Value> = workflows
24        .named_workflows
25        .iter()
26        .map(|(key, config)| {
27            json!({
28                "name": key,
29                "description": config.description.as_deref().unwrap_or(""),
30            })
31        })
32        .collect();
33
34    // Sort by name for consistent output
35    entries.sort_by(|a, b| {
36        let a_name = a.get("name").and_then(|v| v.as_str()).unwrap_or("");
37        let b_name = b.get("name").and_then(|v| v.as_str()).unwrap_or("");
38        a_name.cmp(b_name)
39    });
40
41    // Collect overlays
42    let mut overlay_entries: Vec<Value> = workflows
43        .named_overlays
44        .iter()
45        .map(|(key, config)| {
46            json!({
47                "name": key,
48                "description": config.description.as_deref().unwrap_or(""),
49            })
50        })
51        .collect();
52
53    overlay_entries.sort_by(|a, b| {
54        let a_name = a.get("name").and_then(|v| v.as_str()).unwrap_or("");
55        let b_name = b.get("name").and_then(|v| v.as_str()).unwrap_or("");
56        a_name.cmp(b_name)
57    });
58
59    Ok(json!({
60        "count": entries.len(),
61        "workflows": entries,
62        "overlays": overlay_entries,
63    }))
64}