Skip to main content
Glama
geoffwhittington

SD Elements MCP Server

create_project

Initiate a new project within SD Elements by specifying project details such as name, description, application ID, and phase ID using the SD Elements MCP Server API integration.

Instructions

Create a new project in SD Elements

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
application_idYesID of the application this project belongs to
descriptionNoProject description
nameYesProject name
phase_idNoID of the project phase

Implementation Reference

  • The core handler function for the 'create_project' MCP tool. Decorated with @mcp.tool() for automatic registration. Handles input validation via elicitation for missing name and profile_id, detects profile automatically if possible, constructs API payload, calls the SD Elements API to create the project, and returns JSON response.
    @mcp.tool()
    async def create_project(
        ctx: Context,
        application_id: int,
        name: Optional[str] = None,
        description: Optional[str] = None,
        phase_id: Optional[int] = None,
        profile_id: Optional[str] = None,
    ) -> str:
        """Create a new project in SD Elements. If name is not specified, prompts user to provide it. If profile is not specified, attempts to detect it from project name/description (e.g., 'mobile project' → Mobile profile). If detection fails, prompts user to select from available profiles."""
        global api_client
        if api_client is None:
            api_client = init_api_client()
        
        # Elicitation for name if not provided
        if not name:
            try:
                name_result = await asyncio.wait_for(
                    ctx.elicit(
                        "What is the name of the project you want to create?",
                        response_type=str
                    ),
                    timeout=ELICITATION_TIMEOUT
                )
                if name_result.action != "accept":
                    return json.dumps({"error": "Project creation cancelled: project name is required"})
                name = name_result.data
            except asyncio.TimeoutError:
                return json.dumps({"error": "Elicitation timeout: project name is required. Please provide the 'name' parameter."})
        
        # Elicitation for profile_id if not provided
        if not profile_id:
            profiles_response = api_client.list_profiles({"page_size": 1000})
            profiles = profiles_response.get("results", [])
            
            if not profiles:
                return json.dumps({"error": "No profiles available. Cannot create project without a profile."})
            
            # Try to detect profile from project name/description
            detected_profile_id = detect_profile_from_context(name, description or "", profiles)
            
            if detected_profile_id:
                # Profile detected automatically - use it
                profile_id = detected_profile_id
            else:
                # No profile detected - prompt user to select from available profiles
                profile_options = []
                profile_id_map = {}
                default_profile_id = None
                
                for profile in profiles:
                    profile_name_val = profile.get("name", "Unnamed Profile")
                    profile_id_val = profile.get("id")
                    profile_options.append(profile_name_val)
                    profile_id_map[profile_name_val] = profile_id_val
                    
                    # Track default profile to highlight it in the prompt
                    if profile.get("default", False):
                        default_profile_id = profile_id_val
                
                # Always prompt user to select a profile when detection fails
                prompt_message = "Select a profile:"
                if default_profile_id:
                    # Find default profile name for the prompt
                    default_profile_name = next(
                        (name for name, pid in profile_id_map.items() if pid == default_profile_id),
                        None
                    )
                    if default_profile_name:
                        prompt_message = f"Select a profile (default: {default_profile_name}):"
                
                try:
                    profile_result = await asyncio.wait_for(
                        ctx.elicit(prompt_message, response_type=profile_options),
                        timeout=ELICITATION_TIMEOUT
                    )
                    if profile_result.action != "accept":
                        return json.dumps({"error": "Project creation cancelled: profile selection is required"})
                    profile_id = profile_id_map.get(profile_result.data)
                    if not profile_id:
                        return json.dumps({"error": f"Could not find profile ID for selection: {profile_result.data}"})
                except asyncio.TimeoutError:
                    return json.dumps({"error": "Elicitation timeout: profile selection is required. Please provide the 'profile_id' parameter."})
        
        # Ensure profile_id is set - API requires it
        if not profile_id:
            return json.dumps({"error": "Profile is required but could not be determined. Please specify a profile_id."})
        
        data = {"name": name, "application": application_id}
        if description:
            data["description"] = description
        if phase_id:
            data["phase_id"] = phase_id
        # Profile is required, so always include it
        data["profile"] = profile_id
        
        result = api_client.create_project(data)
        return json.dumps(result, indent=2)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/geoffwhittington/sde-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server