Skip to main content
Glama
jamiesonio

DefectDojo MCP Server

by jamiesonio

update_engagement

Modify engagement details in DefectDojo, including name, target dates, status, description, and tags, using the engagement ID for identification.

Instructions

Update an existing engagement

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
branch_tagNo
build_idNo
commit_hashNo
deduplication_on_engagementNo
descriptionNo
engagement_idYes
engagement_typeNo
lead_idNo
nameNo
statusNo
tagsNo
target_endNo
target_startNo
versionNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The primary handler for the 'update_engagement' MCP tool. Validates inputs, constructs PATCH data from optional parameters, invokes the DefectDojo client API call, and formats the response.
    async def update_engagement(engagement_id: int, name: Optional[str] = None,
                               target_start: Optional[str] = None, # Renamed from start_date
                               target_end: Optional[str] = None,   # Renamed from end_date
                               status: Optional[str] = None,
                               description: Optional[str] = None,
                               # Add other updatable fields from API schema if needed
                               lead_id: Optional[int] = None,
                               version: Optional[str] = None,
                               build_id: Optional[str] = None,
                               commit_hash: Optional[str] = None,
                               branch_tag: Optional[str] = None,
                               engagement_type: Optional[str] = None,
                               deduplication_on_engagement: Optional[bool] = None,
                               tags: Optional[list] = None
                               ) -> Dict[str, Any]:
        """Update an existing engagement. Only provided fields are updated.
    
        Args:
            engagement_id: ID of the engagement to update.
            name: Optional new name.
            target_start: Optional new start date (YYYY-MM-DD).
            target_end: Optional new end date (YYYY-MM-DD).
            status: Optional new status ('Not Started', 'Blocked', 'Cancelled', 'Completed', 'In Progress', 'On Hold', 'Waiting for Resource').
            description: Optional new description.
            lead_id: Optional new lead ID.
            version: Optional new version.
            build_id: Optional new build ID.
            commit_hash: Optional new commit hash.
            branch_tag: Optional new branch/tag.
            engagement_type: Optional new engagement type ('Interactive', 'CI/CD').
            deduplication_on_engagement: Optional new deduplication setting.
            tags: Optional new list of tags (will replace existing tags).
    
        Returns:
            Dictionary with status and data/error.
        """
        # Validate status if provided
        if status:
            valid_statuses = ["Not Started", "Blocked", "Cancelled", "Completed", "In Progress", "On Hold", "Waiting for Resource"]
            if status not in valid_statuses:
                 return {"status": "error", "error": f"Invalid status '{status}'. Must be one of: {', '.join(valid_statuses)}"}
    
        # Validate engagement_type if provided
        if engagement_type and engagement_type not in ["Interactive", "CI/CD"]:
             return {"status": "error", "error": f"Invalid engagement_type '{engagement_type}'. Must be 'Interactive' or 'CI/CD'."}
    
        # Prepare data payload with only provided fields
        data = {}
        if name is not None: data["name"] = name
        if target_start is not None: data["target_start"] = target_start
        if target_end is not None: data["target_end"] = target_end
        if status is not None: data["status"] = status # Send as is after validation
        if description is not None: data["description"] = description
        if lead_id is not None: data["lead"] = lead_id
        if version is not None: data["version"] = version
        if build_id is not None: data["build_id"] = build_id
        if commit_hash is not None: data["commit_hash"] = commit_hash
        if branch_tag is not None: data["branch_tag"] = branch_tag
        if engagement_type is not None: data["engagement_type"] = engagement_type
        if deduplication_on_engagement is not None: data["deduplication_on_engagement"] = deduplication_on_engagement
        if tags is not None: data["tags"] = tags # PATCH usually replaces arrays
    
        # If no fields were provided, return an error
        if not data:
            return {"status": "error", "error": "At least one field must be provided for update"}
    
        client = get_client()
        result = await client.update_engagement(engagement_id, data)
    
        if "error" in result:
            return {"status": "error", "error": result["error"], "details": result.get("details", "")}
    
        return {"status": "success", "data": result}
  • Registration of the update_engagement tool handler using the FastMCP decorator in the central tools.py module, which aggregates all tools.
    mcp.tool(
        name="update_engagement",
        description="Update an existing engagement"
    )(update_engagement)
  • Modular registration of the tool within the engagements_tools.py module's register_tools function.
    mcp.tool(name="update_engagement", description="Update an existing engagement")(update_engagement)
  • Underlying DefectDojoClient method that executes the HTTP PATCH request to the DefectDojo API for updating an engagement.
    async def update_engagement(self, engagement_id: int, data: Dict[str, Any]) -> Dict[str, Any]:
        """Update an existing engagement."""
        return await self._request("PATCH", f"/api/v2/engagements/{engagement_id}/", json=data)
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states this is an update operation, implying mutation, but doesn't disclose any behavioral traits such as required permissions, whether changes are reversible, rate limits, or what the response looks like. For a mutation tool with 14 parameters and no annotations, this is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with just four words, front-loaded with the core action. There's no wasted language, though this comes at the cost of completeness. Every word earns its place in conveying the basic purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (14 parameters, mutation operation, no annotations) and the presence of an output schema, the description is incomplete. It doesn't explain what an 'engagement' is in this context, what fields can be updated, or provide any behavioral context. The output schema helps with return values, but the description should do more for a tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0%, so the description must compensate by explaining parameters. However, it provides no information about any of the 14 parameters, not even the required 'engagement_id'. This leaves the agent with no semantic understanding of what fields can be updated or their purposes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Update an existing engagement' clearly states the verb ('update') and resource ('engagement'), but it's vague about what specific aspects of an engagement can be updated. It doesn't distinguish this tool from sibling tools like 'close_engagement' or 'create_engagement' beyond the basic action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing an existing engagement ID), when not to use it (e.g., for creating new engagements), or how it differs from sibling tools like 'close_engagement' or 'create_engagement'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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/jamiesonio/defectdojo-mcp'

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