Facets Module MCP Server
Automatically extracts git repository metadata to enrich module previews and support version control integration for Terraform modules.
Assists in creating and managing Terraform modules for infrastructure as code, providing tools for module generation, validation, file operations, and scaffolding with metadata and variable management.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Facets Module MCP Server generate a new AWS S3 bucket module with validation"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
> ⚠️ 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 themcp_instructionsdirectory 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 |
| Loads all module writing instructions from the |
| Lists all files in the specified module directory securely within the working directory. |
| Reads the content of a file within the working directory. |
| Apply surgical edits to specific blocks of text in files. Makes precise changes without rewriting entire files. Cannot edit |
| Writes and validates |
| Writes Terraform resource files ( |
| Writes the |
| Writes a |
| Writes files generically with working directory and file type checks. Path: |
| Generates a new Terraform module scaffold with dry-run preview and user confirmation. |
| Validates a Terraform module directory using FTF CLI standards and checks output types. |
| Previews a module by pushing a test version to the control plane with git context extracted automatically. |
| Registers a new output type in the Facets control plane with interfaces and attributes and providers. |
| Retrieves details for a specific output type from the Facets control plane. |
| Finds all output types that include a specific provider source for module configurations. |
| Scans and lists all local Terraform modules by searching for |
| Searches modules by filtering for a string within facets.yaml files, supports pagination, and returns matched modules with details. |
| Retrieves and returns the names of all available test projects for deployment. |
| Tests a module that has been previewed by deploying it to a specified test project. |
| Checks the status of a deployment with optional waiting for completion. |
| Retrieves logs for a specific deployment. |
| Lists all available modules from the control plane that can be forked, displaying them in a compact format for easy selection. |
| 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 uvFor 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 withtest_already_previewed_module, and monitor progress usingcheck_deployment_statusandget_deployment_logs.Employ MCP prompts like
generate_new_moduleto guide module generation interactively, or usefork_existing_moduleto 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 toolsadd_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:
Always run with
dry_run=Truefirst. This is an irreversible action.Parse and display a diff:
Added Modified (old -> new) Removed
Ask the user if they want to edit or add variables and wait for his input.
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
Scored across 30 tools
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 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.
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.
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
Related MCP Connectors
Capability-routed CLI/MCP: signed provenance exports, WCAG-validated themes, sovereign deploy modes.
Manage files and folders directly from your workspace. Read and write files, list directories, cre…
Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.
Deploy and manage Jade Hosting projects from AI clients. Jade account and OAuth required.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenance🌍 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. ⚡️371MIT
- AlicenseCqualityFmaintenanceEnables management of Terraform infrastructure as code through 25 comprehensive tools for operations including plan/apply/destroy, state management, workspace management, and configuration file editing.26MIT
- AlicenseNot gradedqualityDmaintenanceEnables generating, validating, planning, and applying Terraform configurations to manage infrastructure through natural language.MIT
- FlicenseNot gradedqualityAmaintenanceExposes Terraform/Terragrunt tooling as Claude Code tools for generating variables.tf and mock outputs automatically from input files.-