Skip to main content
Glama
Facets Module MCP Server

Facets Module MCP Server

by Facets-cloud

> ⚠️ DEPRECATED: This repository is no longer actively maintained. Please use Praxis instead. If you need this functionality outside of Praxis, use the Raptor CLI.

Facets Module MCP Server

This MCP (Model Context Protocol) Server for the Facets Module assists in creating and managing Terraform modules for infrastructure as code. It integrates with Facets.cloud's FTF CLI, providing secure and robust tools for module generation, validation, and management to support cloud-native infrastructure workflows.

Key Features

  • Secure File Operations
    Limits all file operations to within the working directory to ensure safety and integrity.

  • Modular MCP Tools
    Offers comprehensive tools for file listing, reading, writing, module generation, validation, and previews. All destructive or irreversible commands require explicit user confirmation and support dry-run previews.

  • Facets Module Generation
    Interactive prompt-driven workflows facilitate generation of Terraform modules with metadata, variable, and input management using FTF CLI.

  • Module Forking
    Fork existing modules from the Facets control plane to create customized variants. Supports discovering available modules, updating metadata, and customizing functionality while preserving the original module structure.

  • Supplementary Instructions Support
    Automatically reads additional project-specific instructions from the mcp_instructions directory at the root level, allowing teams to define custom requirements, constraints, and guidelines that supplement the default module generation behavior.

  • Module Preview and Testing
    Comprehensive deployment workflow supporting module preview, testing in dedicated test projects, and real-time deployment monitoring with status checks and logs. You will need a test project with a running environment and an enabled resource added for the module being tested (to be done manually from the Facets UI).

  • Cloud Environment Integration
    Supports multiple cloud providers and automatically extracts git repository metadata to enrich module previews.

Related MCP server: Terraform MCP Server

Available MCP Tools

Tool Name

Description

FIRST_STEP_get_instructions

Loads all module writing instructions from the module_instructions directory and supplementary instructions from mcp_instructions. Always call this first.

list_files

Lists all files in the specified module directory securely within the working directory.

read_file

Reads the content of a file within the working directory.

edit_file_block

Apply surgical edits to specific blocks of text in files. Makes precise changes without rewriting entire files. Cannot edit outputs.tf or facets.yaml files.

write_config_files

Writes and validates facets.yaml configuration files with dry-run and diff previews.

write_resource_file

Writes Terraform resource files (main.tf, variables.tf, etc.) safely. Excludes outputs.tf and facets.yaml.

write_outputs

Writes the outputs.tf file for a module with output attributes and interfaces in a local block.

write_readme_file

Writes a README.md file for the module directory with AI-generated content.

write_generic_file

Writes files generically with working directory and file type checks. Path: facets_mcp/tools/module_files.py

generate_module_with_user_confirmation

Generates a new Terraform module scaffold with dry-run preview and user confirmation.

validate_module

Validates a Terraform module directory using FTF CLI standards and checks output types.

push_preview_module_to_facets_cp

Previews a module by pushing a test version to the control plane with git context extracted automatically.

register_output_type

Registers a new output type in the Facets control plane with interfaces and attributes and providers.

get_output_type_details

Retrieves details for a specific output type from the Facets control plane.

find_output_types_with_provider

Finds all output types that include a specific provider source for module configurations.

get_local_modules

Scans and lists all local Terraform modules by searching for facets.yaml recursively, including loading outputs.tf content if present.

search_modules_after_confirmation

Searches modules by filtering for a string within facets.yaml files, supports pagination, and returns matched modules with details.

list_test_projects

Retrieves and returns the names of all available test projects for deployment.

test_already_previewed_module

Tests a module that has been previewed by deploying it to a specified test project.

check_deployment_status

Checks the status of a deployment with optional waiting for completion.

get_deployment_logs

Retrieves logs for a specific deployment.

list_modules_for_fork

Lists all available modules from the control plane that can be forked, displaying them in a compact format for easy selection.

fork_existing_module

Forks an existing module by downloading it and updating its metadata (flavor and version). Supports dry-run preview and user confirmation.

Prerequisites

The MCP Server requires uv for MCP orchestration.

The package is available on PyPI: facets-module-mcp

Install uv with Homebrew:

brew install uv

For other methods, see the official uv installation guide.

Integration with Claude

Add the following to your claude_desktop_config.json:

{
  "mcpServers": {
    "facets-module": {
      "command": "uvx",
      "args": [
        "facets-module-mcp@latest",
        "/Path/to/working-directory" 
      ],
      "env": {
        "FACETS_PROFILE": "default",
        "FACETS_USERNAME": "<YOUR_USERNAME>",
        "FACETS_TOKEN": "<YOUR_TOKEN>",
        "CONTROL_PLANE_URL": "<YOUR_CONTROL_PLANE_URL>"
      }
    }
  }
}

For a locally cloned repository, use:

{
  "mcpServers": {
    "facets-module": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/your/cloned/facets-module-mcp/facets_mcp",
        "run",
        "facets_server.py",
        "/path/to/working-directory"
      ],
      "env": {
        "PYTHONUNBUFFERED": "1",
        "FACETS_PROFILE": "default",
        "FACETS_USERNAME": "<YOUR_USERNAME>",
        "FACETS_TOKEN": "<YOUR_TOKEN>",
        "CONTROL_PLANE_URL": "<YOUR_CONTROL_PLANE_URL>"
      }
    }
  }
}

⚠ Replace <YOUR_USERNAME>, <YOUR_TOKEN>, and <YOUR_CONTROL_PLANE_URL> with your actual authentication data.

The uv runner automatically manages environment and dependency setup using the pyproject.toml file in the MCP directory.

If you have already logged into FTF, specifying FACETS_PROFILE is sufficient.


For token generation and authentication setup, please refer to the official Facets documentation:
https://readme.facets.cloud/reference/authentication-setup

Note: Similar setup is available in Cursor read here

Usage Highlights

  • Use core tools (list_files, read_file, edit_file_block, write_config_files, etc.) for Terraform code management.

  • Use FTF CLI integration tools for module scaffolding, validation, and preview workflows.

  • Complete deployment flow: preview modules with push_preview_module_to_facets_cp, test on dedicated test projects with test_already_previewed_module, and monitor progress using check_deployment_status and get_deployment_logs.

  • Employ MCP prompts like generate_new_module to guide module generation interactively, or use fork_existing_module to customize existing modules.

  • All destructive actions require explicit user confirmation and dry-run previews.


Module Forking Use Cases

The MCP server now supports forking existing modules from the Facets control plane. Use the "Fork Existing Module" prompt to access a guided workflow for:

  • Security enhancements: Fork a basic module to add additional security controls or compliance requirements

  • Cloud provider adaptations: Adapt modules for different cloud providers while maintaining core functionality

  • Performance optimizations: Create high-performance variants of existing modules with enhanced configurations

  • Feature customizations: Add organization-specific features or integrations to existing modules

  • Version updates: Modernize older modules with updated provider versions or new Terraform features

The fork workflow maintains the original module structure while allowing you to customize metadata, variables, resources, and outputs to meet your specific requirements.


Example Usage

For a comprehensive example of how to use this MCP server with Claude, check out this chat session: Creating a Terraform Module with Facets MCP

This example demonstrates the complete workflow from module generation to testing and deployment.


📘 Additional Guide

For a detailed, real-world walkthrough of building a secure S3 bucket module with AI on the Facets platform, check out
GUIDE.md – Building Facets Modules with AI: A Practical Guide

This guide demonstrates the full conversation flow—requirements, design refinement, implementation review, validation, testing, and iteration—using a developer-focused example tailored for a banking use case.


License

This project is licensed under the MIT License. You are free to use, modify, and distribute it under its terms.

Available Tools

30 tools
add_import_declarationA

Add import declaration to facets.yaml. Use after discovering resources with discover_terraform_resources. For count resources, add index parameter. For for_each resources, add key parameter.

Args: module_path (str): Path to the module directory name (str): Name for the import declaration resource (str, optional): Resource address like 'aws_s3_bucket.bucket' resource_address (str, optional): Full address like 'aws_s3_bucket.bucket[0]' index (str, optional): Index for count resources ('0', '1', or '') key (str, optional): Key for for_each resources ('prod', 'dev', or '') required (bool): Whether import is required (default: True)

Returns: str: JSON response with success status and details

Inputs: module_path (required), name (required), resource, resource_address, +3 more. Returns: result

check_deployment_statusA

Check the status of a deployment.

Args: cluster_id (str): The ID of the environment where the deployment is running release_trace_id (str): The release trace ID of the deployment to check wait (bool): If True, wait for the deployment to complete (either succeed or fail) timeout_seconds (int): Maximum time to wait for completion in seconds (default: 300s / 5min) poll_interval_seconds (int): Time between status checks in seconds (default: 5s)

Returns: str: JSON with deployment status information

Inputs: cluster_id (required), release_trace_id (required), wait, timeout_seconds, +1 more. Returns: result

create_or_update_intentA

Create a new intent or update an existing one in the control plane.

Args: name (str): The intent name (e.g., 'kubernetes_cluster') intent_type (str): The intent type/category (e.g., 'K8s', 'Storage') display_name (str): Human-readable display name description (str): Description of the intent icon_url (str, optional): URL to SVG icon (optional). NEVER send this unless the user explicitly provides it.

Returns: str: JSON response containing success/failure information

Inputs: name (required), intent_type (required), display_name (required), description (required), +1 more. Returns: result

discover_terraform_resourcesA

Discover all Terraform resources in a module directory. Use this first to see what resources are available for import. Returns list of resources with their addresses and whether they use count/for_each.

Args: module_path (str): Path to the module directory containing Terraform files

Returns: str: JSON with resources list, showing resource_address, has_count, has_for_each for each resource

Inputs: module_path (required). Returns: result

edit_file_blockA

Apply surgical edits to specific blocks of text in a file. Make Sure you have Called FIRST_STEP_get_instructions first before this tool.

Makes precise changes to files by finding and replacing exact text matches. This is safer than rewriting entire files.

RESTRICTIONS:

  • Cannot edit outputs.tf files - use write_outputs tool instead

  • Cannot edit facets.yaml files - use write_config_files tool instead

Best practices:

  • Include enough context in old_string to make it unique

  • Use expected_replacements=1 for safety (default)

  • For multiple replacements, specify the exact count expected

Args: file_path (str): Path to the file to edit (must be within working directory) old_string (str): Exact text to find and replace (include context for uniqueness) new_string (str): Replacement text expected_replacements (int): Expected number of matches (default: 1, prevents unintended changes)

Returns: str: JSON formatted response with success status, message, and optional error details

Inputs: file_path (required), old_string (required), new_string (required), expected_replacements. Returns: result

find_output_types_with_providerB

This tool finds all output types that include a specific provider source, which can be used as inputs for module configurations.

Args: provider_source (str): The provider source name to search for.

Returns: str: JSON string containing the formatted output type information.

Inputs: provider_source (required). Returns: result

FIRST_STEP_get_instructionsA

ALWAYS Call this tool first before calling any other tool of this mcp. Loads all module writing instructions for Facets module development found in the module_instructions directory and supplementary instructions from the mcp_instructions directory at the root level of the working directory.

Returns: str: A JSON string containing the content of all instruction files, with each file's content stored under its filename as key.

Inputs: no named parameters. Returns: result

fork_existing_moduleA

Fork an existing module by downloading it and updating its metadata.

⚠️ IMPORTANT: REQUIRES USER CONFIRMATION ⚠️ This function performs an irreversible action.

Step 1 - ALWAYS use dry_run=True first. This is an irreversible action. Step 2 - Present the dry run output to the user showing what will be changed. Step 3 - Ask if user wants to make any changes to the fork parameters. Step 4 - Call the tool without dry run to execute the fork.

Args: source_module_id (str): ID of the module to fork from the control plane new_flavor (str): New flavor name for the forked module new_version (str): New version for the forked module (default: "1.0.0") dry_run (bool): If True, shows what would be done without executing (default: True)

Returns: str: JSON formatted response with fork operation details

Inputs: source_module_id (required), new_flavor (required), new_version, dry_run. Returns: result

generate_module_with_user_confirmationA

⚠️ IMPORTANT: REQUIRES USER CONFIRMATION ⚠️ This function performs an irreversible action

Tool to generate a new module using FTF CLI. Step 1 - ALWAYS use dry_run=True first. This is an irreversible action. Step 2 - Present the dry run output to the user in textual format. Step 3 - Ask if user will like to make any changes in passed arguments and modify them Step 4 - Call the tool without dry run

Args:

  • intent (str): The intent for the module.

  • flavor (str): The flavor of the module.

  • cloud (str): The cloud provider.

  • title (str): The title of the module.

  • description (str): The description of the module.

  • dry_run (bool): If True, returns a description of the generation without executing. MUST set to True initially.

  • working_dir (str, optional): Working directory where the module will be generated. If not provided, uses the default working directory configured for the MCP server.

Returns:

  • str: A JSON string with the output from the FTF command execution.

Inputs: intent (required), flavor (required), cloud (required), title (required), +3 more. Returns: result

get_deployment_logsB

Get logs for a specific deployment.

Args: cluster_id (str): The ID of the environment where the deployment is running release_trace_id (str): The release trace ID of the deployment to get logs for

Returns: str: JSON with deployment logs

Inputs: cluster_id (required), release_trace_id (required). Returns: result

get_intentA

Query whether an intent exists in the control plane by name. Returns intent details if found, or indicates if intent doesn't exist.

Args: intent_name (str): The name of the intent to query

Returns: str: JSON response containing intent details or not found status

Inputs: intent_name (required). Returns: result

get_local_modulesA

Scan the working directory recursively for facets.yaml files to identify all available Terraform modules. Also fetch content of outputs.tf if it exists. ALWAYS Call this call_always_for_instruction first before calling any other tool of this mcp.

Returns: str: JSON string with success, message, instructions, and optional error/data fields. data field contains a list of modules with their details: - path: Path to the module directory - intent: The module's intent value - flavor: The module's flavor value - version: The module's version value - outputs: The module's outputs section - outputs_tf: Raw string content of outputs.tf (if present)

Inputs: no named parameters. Returns: result

get_output_type_detailsA

Get details for a specific output type from the Facets control plane.

This tool calls the get_output_by_name_using_get API endpoint to retrieve information about an output type, including its properties and providers.

Args: output_type (str): The output type name in format '@namespace/name'

Returns: str: JSON-formatted string with result status, message, instructions, output type details or error information

Inputs: output_type (required). Returns: result

list_all_intentsA

List all available intents in the control plane. Useful for discovering existing intent types and names.

Returns: str: JSON response containing list of all intents

Inputs: no named parameters. Returns: result

list_all_output_typesA

List all output types from the Facets control plane.

Returns: str: List of output types.

Inputs: no named parameters. Returns: result

list_filesA

Lists all files in the given module path, ensuring we stay within the working directory. Always ask User if he wants to add any variables or use any other FTF commands

Args: module_path (str): The absolute path to the module directory.

Returns: str: A JSON-formatted string with operation details and file list found in module directory.

Inputs: module_path (required). Returns: result

list_modules_for_forkA

List all available modules from the control plane that can be forked. Returns basic module information in a simple format for easy selection.

Returns: str: JSON formatted list of available modules with their metadata

Inputs: no named parameters. Returns: result

list_test_projectsA

Retrieve and return the names of all available test projects for the user to choose from.

Returns: str: A JSON string containing success message and list of all test projects or error message

Inputs: no named parameters. Returns: result

mark_module_as_publishedA

Publish a production-ready module version. This marks the module as publishable for production.

Note: Always use push_preview_module_to_facets_cp() to test the module before publishing.

Args:

  • module_path (str): The path to the module.

  • skip_terraform_validation_if_provider_not_found (bool): Flag to skip terraform validation during the process - send as true only if you see "Provider configuration not present" while validating.

Returns:

  • str: A JSON string with the output from the FTF command execution.

Inputs: module_path (required), skip_terraform_validation_if_provider_not_found. Returns: result

push_preview_module_to_facets_cpA

Tool to preview a module using FTF CLI. This will push a Test version of module to control plane. Git repository details are automatically extracted from the local working directory's .git folder.

Args:

  • module_path (str): The path to the module.

  • skip_terraform_validation_if_provider_not_found (bool): Flag to skip terraform validation during the process - send as true only if you see "Provider configuration not present" while validating.

Returns:

  • str: A JSON string with the output from the FTF command execution.

Inputs: module_path (required), skip_terraform_validation_if_provider_not_found. Returns: result

read_fileB

Reads the content of a file, ensuring it is within the working directory. Make Sure you have Called FIRST_STEP_get_instructions first before this tool.

Args: file_path (str): The path to the file.

Returns: str: JSON formatted response with file content or error information.

Inputs: file_path (required). Returns: result

register_output_typeA

Tool to register a new output type in the Facets control plane.

This tool first checks if the output type already exists:

  • If it doesn't exist, it proceeds with registration

  • If it exists, it compares properties and providers to determine if an update is needed

Args:

  • name (str): The name of the output type in the format '@namespace/name'.

  • interfaces (Dict[str, Any], optional): Dictionary of output interfaces as JSON schema. Each key is an interface name, value is a JSON schema definition.

  • attributes (Dict[str, Any], optional): Dictionary of output attributes as JSON schema. Each key is an attribute name, value is a JSON schema definition.

    Example: { "default": { "type": "object", "properties": { "topic_name": {"type": "string"}, "topic_id": {"type": "string"} } } }

    ❌ INCORRECT (do NOT wrap field names in outer "properties" key): { "properties": { "default": {...} } }

  • providers (List[Dict[str, str]], optional): List of provider dictionaries with 'name', 'source', and 'version'.

  • override_confirmation (bool): Flag to confirm overriding existing output type if different properties/providers found.

Returns:

  • str: A JSON string with the output from the FTF command execution, error message, or request for confirmation.

Inputs: name (required), interfaces, attributes, providers, +1 more. Returns: result

search_modules_after_confirmationA
Search for a specific string in all facets.yaml files to filter modules.
This tool should only be used after confirming search intent with the user.

For exploratory searches, first explain search capabilities before executing.

Args:
    search_string (str): The string to search for in modules.
    page (int): The page number for pagination.

Returns:
    str: JSON string with success, message, instructions, and optional error/data fields. data field contains the filtered modules along with their details.

Inputs: search_string (required), page. Returns: result

test_already_previewed_moduleB

Test a module that has been previewed by asking the user for the project_name where it needs to be tested.

This tool checks if the project exists, verifies if it supports preview modules, and then does terraform apply. You can check logs for the apply using get_deployment_logs, and check the status of the deployment using check_deployment_status.

Args: project_name (str): The name of the test project (stack) to deploy to intent (str): The intent of the module to deploy flavor (str): The flavor of the module to deploy version (str): The version of the module to deploy environment_name (str, optional): The specific environment name to deploy to. Provide this only if the user has asked you to.

Returns: str: Result of the deployment operation as a JSON string

Inputs: project_name (required), intent (required), flavor (required), version (required), +1 more. Returns: result

validate_moduleA

Tool to validate a module directory using FTF CLI.

This tool checks if a Terraform module directory meets the FTF standards. It validates the structure, formatting, required files, and output types of the module. It also checks that all output types referenced in outputs and inputs blocks exist in the Facets control plane.

Args:

  • module_path (str): The path to the module.

  • check_only (bool): Flag to only check formatting without applying changes.

  • skip_terraform_validation_if_provider_not_found (bool): Flag to skip terraform validation during the process - send as true only if you see "Provider configuration not present" while validating.

Returns:

  • str: A JSON string with the output from the FTF command execution or error message if validation fails.

Inputs: module_path (required), check_only, skip_terraform_validation_if_provider_not_found. Returns: result

write_config_filesA

Writes facets.yaml configuration file for a Terraform module. Make Sure you have Called FIRST_STEP_get_instructions first before this tool.

Steps for safe variable update:

  1. Always run with dry_run=True first. This is an irreversible action.

  2. Parse and display a diff:

    Added Modified (old -> new) Removed

  3. Ask the user if they want to edit or add variables and wait for his input.

  4. Only if the user explicitly confirms, run again with dry_run=False.

Args: module_path (str): Path to the module directory. facets_yaml (str): Content for facets.yaml file. dry_run (bool): If True, returns a preview of changes without making them. Default is True.

Returns: str: Success message, diff preview (if dry_run=True), or error message.

Inputs: module_path (required), facets_yaml (required), dry_run. Returns: result

write_generic_fileA

Writes a generic file to the module directory, except for .tf files, facets.yaml, or README.md. Can be used to add supporting files like Python or Bash scripts if needed by the module.

Fails if trying to write a forbidden file. Checks working directory as in other tools.

Args: module_path (str): Path to the module directory. file_name (str): Name of the file to write. content (str): Content to write to the file.

Returns: str: JSON string with success status, message, instructions, and optional error/data.

Inputs: module_path (required), file_name (required), content (required). Returns: result

write_outputsA

Write the outputs.tf file for a module with properly formatted Terraform locals block.

Each field must have 'value' (any type: string, bool, number, list, dict) and 'sensitive' (bool) keys.

Args: module_path (str): Path to the module directory (must contain facets.yaml). output_attributes (dict): Map where each field is: {"value": , "sensitive": bool} output_interfaces (dict): Map where each field is: {"value": , "sensitive": bool}

Example: write_outputs( module_path="/path/to/module", output_attributes={ "instance_id": {"value": "aws_instance.example.id", "sensitive": False}, "config": {"value": {"region": "us-east-1", "zone": "a"}, "sensitive": False}, "api_keys": {"value": ["key1", "key2"], "sensitive": True}, "enabled": {"value": True, "sensitive": False} } )

Returns: str: JSON formatted success or error message.

Inputs: module_path (required), output_attributes, output_interfaces. Returns: result

write_readme_fileA

Writes a README.md file for the module directory. This tool is intended for AI to generate the README content for the module.

Args: module_path (str): Path to the module directory. content (str): Content to write to README.md.

Returns: str: JSON string with success status, message, instructions, and optional error/data.

Inputs: module_path (required), content (required). Returns: result

write_resource_fileA

Writes a Terraform resource file (main.tf, variables.tf, etc.) to a module directory.

Does NOT allow writing output(s).tf here. To update outputs.tf, use write_outputs().

Args: module_path (str): Path to the module directory. file_name (str): Name of the file to write (e.g., "main.tf", "variables.tf"). content (str): Content to write to the file.

Returns: str: JSON string with success, message, instructions, and optional error/data fields.

Inputs: module_path (required), file_name (required), content (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 30 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes, especially the write_* family which is carefully partitioned by file type. A few clusters (output type queries, file-writing helpers) could cause initial confusion, but their descriptions resolve the boundaries.

    Naming Consistency4/5

    Naming is mostly consistent snake_case verb_noun: write_resource_file, list_all_intents, check_deployment_status, validate_module. A few odd exceptions like push_preview_module_to_facets_cp, test_already_previewed_module, and FIRST_STEP_get_instructions break the pattern.

    Tool Count2/5

    30 tools is above the 25+ threshold and feels heavy for an MCP surface. The scope is broad, but several write, list, and query helpers could likely be consolidated.

    Completeness4/5

    The module lifecycle is well covered: instructions, file read/write, generation, forking, validation, import, preview, publish, and test. Minor gaps like missing delete/update operations for intents and output types prevent a perfect score.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      🌍 Terraform Model Context Protocol (MCP) Tool - An experimental CLI tool that enables AI assistants to manage and operate Terraform environments. Supports reading Terraform configurations, analyzing plans, applying configurations, and managing state with Claude Desktop integration. ⚡️
      371
      MIT