Skip to main content
Glama
severity1

terraform-cloud-mcp

update_project

Modify Terraform Cloud project settings like name, description, auto-destroy duration, or tags. Only specified attributes are updated while others remain unchanged.

Instructions

Update an existing project.

Modifies the settings of a Terraform Cloud project. This can be used to change attributes like name, description, auto-destroy duration, or tags. Only specified attributes will be updated; unspecified attributes remain unchanged.

API endpoint: PATCH /projects/{project_id}

Args: project_id: The ID of the project to update (format: "prj-xxxxxxxx") params: Project parameters to update (optional): - name: New name for the project - description: Human-readable description of the project - auto_destroy_activity_duration: How long each workspace should wait before auto-destroying (e.g., '14d', '24h') - tag_bindings: List of tag key-value pairs to bind to the project

Returns: The updated project with all current settings and configuration

See: docs/tools/project.md for reference documentation

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYes
paramsNo

Implementation Reference

  • The handler function that executes the 'update_project' tool. It constructs the API payload using Pydantic models and sends a PATCH request to update the project in Terraform Cloud.
    async def update_project(
        project_id: str, params: Optional[ProjectParams] = None
    ) -> APIResponse:
        """Update an existing project.
    
        Modifies the settings of a Terraform Cloud project. This can be used to change
        attributes like name, description, auto-destroy duration, or tags. Only specified
        attributes will be updated; unspecified attributes remain unchanged.
    
        API endpoint: PATCH /projects/{project_id}
    
        Args:
            project_id: The ID of the project to update (format: "prj-xxxxxxxx")
            params: Project parameters to update (optional):
                - name: New name for the project
                - description: Human-readable description of the project
                - auto_destroy_activity_duration: How long each workspace should wait before
                  auto-destroying (e.g., '14d', '24h')
                - tag_bindings: List of tag key-value pairs to bind to the project
    
        Returns:
            The updated project with all current settings and configuration
    
        See:
            docs/tools/project.md for reference documentation
        """
        # Extract parameters from the params object if provided
        param_dict = params.model_dump(exclude_none=True) if params else {}
    
        # Create request using Pydantic model
        request = ProjectUpdateRequest(project_id=project_id, **param_dict)
    
        # Create base API payload using utility function
        payload = create_api_payload(
            resource_type="projects",
            model=request,
            exclude_fields={"project_id"},
        )
    
        # Handle tag bindings if present
        if request.tag_bindings:
            tag_bindings_data = []
            for tag in request.tag_bindings:
                tag_bindings_data.append(
                    {
                        "type": "tag-bindings",
                        "attributes": {"key": tag.key, "value": tag.value},
                    }
                )
    
            if "relationships" not in payload["data"]:
                payload["data"]["relationships"] = {}
    
            payload["data"]["relationships"]["tag-bindings"] = {"data": tag_bindings_data}
    
        # Remove tag-bindings from attributes if present since we've moved them to relationships
        if "tag-bindings" in payload["data"]["attributes"]:
            del payload["data"]["attributes"]["tag-bindings"]
    
        # Log payload for debugging
        logger = logging.getLogger(__name__)
        logger.debug(f"Update project payload: {payload}")
    
        # Make API request
        return await api_request(f"projects/{project_id}", method="PATCH", data=payload)
  • Pydantic model used as input parameter 'params' for the update_project tool, defining optional fields like name, description, auto_destroy_activity_duration, and tag_bindings.
    class ProjectParams(BaseProjectRequest):
        """Parameters for project operations without routing fields.
    
        This model provides all optional parameters for creating or updating projects,
        reusing field definitions from BaseProjectRequest. It separates configuration
        parameters from routing information like organization and project ID.
    
        Reference: https://developer.hashicorp.com/terraform/cloud-docs/api-docs/projects
    
        Note:
            When updating a project, use this model to specify only the attributes
            you want to change. Unspecified attributes retain their current values.
            All fields are inherited from BaseProjectRequest.
    
        See:
            docs/models/project.md for reference
        """
    
        # Inherits model_config and all fields from BaseProjectRequest
  • Internal Pydantic model used within the handler to structure the update request payload, extending BaseProjectRequest with project_id.
    class ProjectUpdateRequest(BaseProjectRequest):
        """Request model for updating a Terraform Cloud project.
    
        Validates and structures the request for updating projects. Extends BaseProjectRequest
        with routing fields while keeping all configuration fields optional.
    
        Reference: https://developer.hashicorp.com/terraform/cloud-docs/api-docs/projects#update-a-project
    
        Note:
            This inherits all configuration fields from BaseProjectRequest
            and adds required routing field for the update operation.
    
        See:
            docs/models/project.md for reference
        """
    
        # Add project_id which is required for updates but not part of the project attributes payload
        project_id: str = Field(
            ...,
            description="The ID of the project to update",
        )
  • Registers the update_project handler as an MCP tool with write permissions configuration.
    mcp.tool(**write_tool_config)(projects.update_project)
Behavior4/5

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

Annotations provide readOnlyHint=false, indicating this is a mutation tool. The description adds valuable behavioral context beyond annotations: it specifies that only specified attributes are updated (partial update behavior), mentions the API endpoint (PATCH /projects/{project_id}), and describes the return value. It doesn't contradict annotations, and adds useful implementation details that help the agent understand how the tool behaves.

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

Conciseness4/5

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

The description is well-structured with clear sections (purpose, behavior, args, returns, see). It's appropriately sized at 9 sentences, with the core information front-loaded. The 'Args' and 'Returns' sections could be slightly more concise, but overall it's efficient with minimal waste.

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

Completeness4/5

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

For a mutation tool with 2 parameters, 0% schema coverage, no output schema, and readOnlyHint=false annotation, the description provides strong coverage: clear purpose, behavioral context, full parameter documentation, and return value explanation. It lacks explicit error handling or permission requirements, but given the context signals, it's mostly complete. The 'See' reference adds helpful documentation linkage.

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

Parameters5/5

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

Schema description coverage is 0%, so the description carries full burden for parameter documentation. It provides excellent parameter semantics: clearly documents both parameters (project_id and params), explains the format for project_id ('prj-xxxxxxxx'), lists the four updatable fields within params with examples for auto_destroy_activity_duration, and explains that params is optional. This fully compensates for the lack of schema descriptions.

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

Purpose5/5

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

The description clearly states the verb ('Update'), resource ('an existing project'), and scope ('Terraform Cloud project'). It distinguishes from siblings like 'create_project' by specifying it's for existing projects, and from 'update_organization' or 'update_workspace' by focusing on projects. The purpose is specific and well-differentiated.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool ('Modifies the settings of a Terraform Cloud project') and mentions it's for updating existing projects, which distinguishes it from 'create_project'. However, it doesn't explicitly state when NOT to use it or mention alternatives like 'update_workspace' or 'update_organization' for other resources. The guidance is clear but lacks explicit exclusions.

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

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/severity1/terraform-cloud-mcp'

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