Skip to main content

foundry_mcp/core/ops/
list_projects.rs

1//! Core op for listing projects (tool-agnostic)
2
3use anyhow::{Context, Result};
4
5use crate::core::foundry;
6use crate::types::responses::{FoundryResponse, ListProjectsResponse, ProjectInfo};
7use crate::utils::formatting::format_count;
8use crate::utils::response::build_success_response;
9
10#[derive(Debug, Clone)]
11pub struct Input;
12
13pub async fn run(_input: Input) -> Result<FoundryResponse<ListProjectsResponse>> {
14    let foundry = foundry::get_default_foundry()?;
15
16    let project_metadata_list = foundry
17        .list_projects()
18        .await
19        .context("Failed to list projects from foundry directory")?;
20
21    let projects: Vec<ProjectInfo> = project_metadata_list
22        .into_iter()
23        .map(|metadata| {
24            // Use the location_hint if available, otherwise use "Unknown"
25            let project_path = format!("~/.foundry/{}", metadata.name);
26
27            ProjectInfo {
28                name: metadata.name,
29                created_at: metadata.created_at,
30                spec_count: metadata.spec_count,
31                path: project_path,
32            }
33        })
34        .collect();
35
36    let response_data = ListProjectsResponse { projects };
37
38    let (next_steps, workflow_hints) = if response_data.projects.is_empty() {
39        (
40            vec![
41                "No projects found in foundry directory - ready for project creation".to_string(),
42                "You can create your first project with: mcp_foundry_create_project".to_string(),
43            ],
44            vec![
45                "You can use 'mcp_foundry_get_foundry_help workflows' for getting started guidance"
46                    .to_string(),
47                "Projects are stored in ~/.foundry/ directory for easy access".to_string(),
48            ],
49        )
50    } else {
51        let project_count = response_data.projects.len();
52        (
53            vec![
54                format_count(project_count, "project", "projects"),
55                "You can use 'mcp_foundry_create_spec <project_name> <feature_name>' to add specifications".to_string(),
56                "You can use 'mcp_foundry_load_spec <project_name>' to view existing specifications".to_string(),
57            ],
58            vec![
59                "Each project can contain multiple timestamped specifications for organized development".to_string(),
60                "You can use 'mcp_foundry_analyze_project' to add project analysis to existing codebases".to_string(),
61            ],
62        )
63    };
64
65    Ok(build_success_response(
66        response_data,
67        next_steps,
68        workflow_hints,
69    ))
70}