Skip to main content
Glama
itshare4u

Agent Knowledge MCP

create_snapshot

Backup Elasticsearch indices with configurable options for repository management, index selection, and cluster state inclusion.

Instructions

Create a snapshot (backup) of Elasticsearch indices with comprehensive options and repository management

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
snapshot_nameYesName for the snapshot (must be unique)
repositoryNoRepository name to store the snapshotbackup_repository
indicesNoComma-separated list of indices to backup (default: all indices)
ignore_unavailableNoWhether to ignore unavailable indices
include_global_stateNoWhether to include cluster global state
wait_for_completionNoWhether to wait for snapshot completion
descriptionNoOptional description for the snapshot

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The primary handler for the 'create_snapshot' tool. This async function, decorated with @app.tool(), implements the complete logic: validates inputs via Annotated Fields (serving as schema), creates/checks repository, executes snapshot via Elasticsearch client, handles wait_for_completion, provides detailed success/error messages with emojis, suggestions, and technical details.
    @app.tool(
        description="Create a snapshot (backup) of Elasticsearch indices with comprehensive options and repository management",
        tags={"elasticsearch", "snapshot", "backup", "repository"}
    )
    async def create_snapshot(
            snapshot_name: Annotated[str, Field(description="Name for the snapshot (must be unique)")],
            repository: Annotated[str, Field(description="Repository name to store the snapshot")] = "backup_repository",
            indices: Annotated[Optional[str], Field(
                description="Comma-separated list of indices to backup (default: all indices)")] = None,
            ignore_unavailable: Annotated[bool, Field(description="Whether to ignore unavailable indices")] = True,
            include_global_state: Annotated[bool, Field(description="Whether to include cluster global state")] = True,
            wait_for_completion: Annotated[bool, Field(description="Whether to wait for snapshot completion")] = True,
            description: Annotated[Optional[str], Field(description="Optional description for the snapshot")] = None
    ) -> str:
        """Create a snapshot (backup) of Elasticsearch indices."""
        try:
            es = get_es_client()
    
            # Check if repository exists, create if not
            try:
                repo_info = es.snapshot.get_repository(repository=repository)
            except:
                # Repository doesn't exist, create default file system repository
                repo_body = {
                    "type": "fs",
                    "settings": {
                        "location": f"/usr/share/elasticsearch/snapshots/{repository}",
                        "compress": True
                    }
                }
                try:
                    es.snapshot.create_repository(repository=repository, body=repo_body)
                    repo_created = True
                except Exception as repo_error:
                    return (f"โŒ Failed to create snapshot repository:\n\n" +
                            f"๐Ÿ”ง **Repository Error**: Cannot create repository '{repository}'\n" +
                            f"๐Ÿ“ **Issue**: {str(repo_error)}\n\n" +
                            f"๐Ÿ’ก **Common Solutions**:\n" +
                            f"   1. Ensure Elasticsearch has write permissions to snapshot directory\n" +
                            f"   2. Add 'path.repo: [\"/usr/share/elasticsearch/snapshots\"]' to elasticsearch.yml\n" +
                            f"   3. Restart Elasticsearch after configuration change\n" +
                            f"   4. Or use existing repository name\n\n" +
                            f"๐Ÿ” **Technical Details**: {str(repo_error)}")
            else:
                repo_created = False
    
            # Parse indices parameter
            if indices:
                indices_list = [idx.strip() for idx in indices.split(',')]
                indices_param = ','.join(indices_list)
            else:
                indices_param = "*"  # All indices
                indices_list = ["*"]
    
            # Create snapshot metadata
            snapshot_body = {
                "indices": indices_param,
                "ignore_unavailable": ignore_unavailable,
                "include_global_state": include_global_state
            }
    
            if description:
                snapshot_body["metadata"] = {
                    "description": description,
                    "created_by": "AgentKnowledgeMCP",
                    "created_at": datetime.now().isoformat()
                }
    
            # Create the snapshot
            snapshot_result = es.snapshot.create(
                repository=repository,
                snapshot=snapshot_name,
                body=snapshot_body,
                wait_for_completion=wait_for_completion
            )
    
            # Format response based on completion
            if wait_for_completion:
                snapshot_info = snapshot_result.get('snapshot', {})
                state = snapshot_info.get('state', 'UNKNOWN')
    
                if state == 'SUCCESS':
                    status_emoji = "โœ…"
                    status_msg = "Successfully completed"
                elif state == 'PARTIAL':
                    status_emoji = "โš ๏ธ"
                    status_msg = "Partially completed with some issues"
                elif state == 'FAILED':
                    status_emoji = "โŒ"
                    status_msg = "Failed to complete"
                else:
                    status_emoji = "๐Ÿ”„"
                    status_msg = f"Status: {state}"
    
                result_message = (f"{status_emoji} Snapshot '{snapshot_name}' {status_msg}!\n\n" +
                                  f"๐Ÿ“ธ **Snapshot Details**:\n" +
                                  f"   ๐Ÿ“‚ Repository: {repository}\n" +
                                  f"   ๐Ÿ“‹ Name: {snapshot_name}\n" +
                                  f"   ๐Ÿ“Š State: {state}\n" +
                                  f"   ๐Ÿ“ฆ Indices: {', '.join(indices_list)}\n" +
                                  f"   ๐ŸŒ Global State: {'Included' if include_global_state else 'Excluded'}\n")
    
                if snapshot_info.get('shards'):
                    shards = snapshot_info['shards']
                    result_message += (f"   ๐Ÿ”ข Shards: {shards.get('total', 0)} total, " +
                                       f"{shards.get('successful', 0)} successful, " +
                                       f"{shards.get('failed', 0)} failed\n")
    
                if snapshot_info.get('start_time_in_millis') and snapshot_info.get('end_time_in_millis'):
                    duration = (snapshot_info['end_time_in_millis'] - snapshot_info['start_time_in_millis']) / 1000
                    result_message += f"   โฑ๏ธ Duration: {duration:.2f} seconds\n"
    
                if description:
                    result_message += f"   ๐Ÿ“ Description: {description}\n"
    
            else:
                result_message = (f"๐Ÿ”„ Snapshot '{snapshot_name}' started!\n\n" +
                                  f"๐Ÿ“ธ **Snapshot Details**:\n" +
                                  f"   ๐Ÿ“‚ Repository: {repository}\n" +
                                  f"   ๐Ÿ“‹ Name: {snapshot_name}\n" +
                                  f"   ๐Ÿ“Š Status: Running in background\n" +
                                  f"   ๐Ÿ“ฆ Indices: {', '.join(indices_list)}\n" +
                                  f"   ๐ŸŒ Global State: {'Included' if include_global_state else 'Excluded'}\n")
    
            if repo_created:
                result_message += f"\n๐Ÿ†• **Repository Created**: Created new repository '{repository}'\n"
    
            result_message += (f"\nโœ… **Success Actions**:\n" +
                               f"   ๐Ÿ“ธ Snapshot backup is {'completed' if wait_for_completion else 'in progress'}\n" +
                               f"   ๐Ÿ” Use 'list_snapshots' to view all snapshots\n" +
                               f"   ๐Ÿ”„ Use 'restore_snapshot' to restore from this backup\n" +
                               f"   ๐Ÿ“Š Check snapshot status with repository '{repository}'\n\n" +
                               f"๐Ÿ’พ **Backup Strategy**:\n" +
                               f"   ๐Ÿ•’ Regular snapshots help protect against data loss\n" +
                               f"   ๐Ÿท๏ธ Use descriptive snapshot names with dates\n" +
                               f"   ๐Ÿ“‚ Monitor repository storage space\n" +
                               f"   ๐Ÿงน Clean up old snapshots periodically")
    
            return result_message
    
        except Exception as e:
            error_message = "โŒ Failed to create snapshot:\n\n"
    
            error_str = str(e).lower()
            if "connection" in error_str or "refused" in error_str:
                error_message += "๐Ÿ”Œ **Connection Error**: Cannot connect to Elasticsearch server\n"
                error_message += f"๐Ÿ“ Check if Elasticsearch is running at the configured address\n"
                error_message += f"๐Ÿ’ก Try: Use 'setup_elasticsearch' tool to start Elasticsearch\n\n"
            elif "repository" in error_str and ("not found" in error_str or "missing" in error_str):
                error_message += f"๐Ÿ“‚ **Repository Error**: Repository '{repository}' not found or misconfigured\n"
                error_message += f"๐Ÿ“ Check repository configuration and permissions\n"
                error_message += f"๐Ÿ’ก Try: Use different repository name or check path.repo settings\n\n"
            elif "invalid_snapshot_name" in error_str:
                error_message += f"๐Ÿท๏ธ **Naming Error**: Invalid snapshot name '{snapshot_name}'\n"
                error_message += f"๐Ÿ“ Snapshot names must be lowercase and cannot contain certain characters\n"
                error_message += f"๐Ÿ’ก Try: Use alphanumeric characters and hyphens only\n\n"
            elif "already_exists" in error_str:
                error_message += f"๐Ÿ“‹ **Conflict Error**: Snapshot '{snapshot_name}' already exists\n"
                error_message += f"๐Ÿ“ Each snapshot must have a unique name within the repository\n"
                error_message += f"๐Ÿ’ก Try: Use different snapshot name or delete existing snapshot\n\n"
            else:
                error_message += f"โš ๏ธ **Unknown Error**: {str(e)}\n\n"
    
            error_message += f"๐Ÿ” **Technical Details**: {str(e)}"
            return error_message
  • Registration of the elasticsearch_snapshots sub-server (containing create_snapshot) into the main unified Elasticsearch FastMCP app via app.mount(snapshots_app). This mounts all 6 sub-servers, making the tool available in the primary interface.
    print("๐Ÿ—๏ธ Mounting Elasticsearch sub-servers...")
    
    # Mount all sub-servers into unified interface
    app.mount(snapshots_app)           # 3 tools: snapshot management
    app.mount(index_metadata_app)      # 3 tools: metadata governance  
    app.mount(document_app)            # 3 tools: document operations
    app.mount(index_app)               # 3 tools: index management
    app.mount(search_app)              # 2 tools: search & validation
    app.mount(batch_app)               # 2 tools: batch operations
    
    print("โœ… All 6 sub-servers mounted successfully! Total: 16 tools available")
  • Input schema defined via function parameters with typing.Annotated and pydantic.Field for validation: snapshot_name (required str), repository (str default), indices (opt str), ignore_unavailable (bool), include_global_state (bool), wait_for_completion (bool), description (opt str). Output: str status message.
    async def create_snapshot(
            snapshot_name: Annotated[str, Field(description="Name for the snapshot (must be unique)")],
            repository: Annotated[str, Field(description="Repository name to store the snapshot")] = "backup_repository",
            indices: Annotated[Optional[str], Field(
                description="Comma-separated list of indices to backup (default: all indices)")] = None,
            ignore_unavailable: Annotated[bool, Field(description="Whether to ignore unavailable indices")] = True,
            include_global_state: Annotated[bool, Field(description="Whether to include cluster global state")] = True,
            wait_for_completion: Annotated[bool, Field(description="Whether to wait for snapshot completion")] = True,
            description: Annotated[Optional[str], Field(description="Optional description for the snapshot")] = None
    ) -> str:
  • Initial tool registration on the sub-server FastMCP app instance via @app.tool() decorator with description and tags.
    @app.tool(
        description="Create a snapshot (backup) of Elasticsearch indices with comprehensive options and repository management",
        tags={"elasticsearch", "snapshot", "backup", "repository"}
    )
Behavior2/5

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

With no annotations provided, the description carries full burden but offers minimal behavioral insight. It mentions 'comprehensive options' but doesn't detail critical behaviors like permissions needed, impact on system performance during backup, whether snapshots are incremental, or error handling. This is inadequate for a mutation tool with complex operations.

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 a single, efficient sentence that front-loads the core purpose. It avoids redundancy but could be slightly more structured by separating functional intent from capability notes.

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

Completeness3/5

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

Given the tool's complexity (7 parameters, mutation operation) and lack of annotations, the description is insufficiently complete. It doesn't address behavioral aspects like side effects or error cases, though the presence of an output schema mitigates some gaps by handling return values externally.

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

Parameters3/5

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

Schema description coverage is 100%, so parameters are well-documented in the schema. The description adds little beyond implying scope ('Elasticsearch indices') and hinting at flexibility ('comprehensive options'), but doesn't clarify parameter interactions or provide examples, meeting the baseline for high schema coverage.

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

Purpose4/5

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

The description clearly states the action ('Create a snapshot') and resource ('Elasticsearch indices'), specifying it's a backup operation. It distinguishes from sibling 'restore_snapshot' by focusing on creation rather than restoration, though it doesn't explicitly contrast with other backup-related tools.

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?

No explicit guidance on when to use this tool versus alternatives. While it mentions 'comprehensive options and repository management,' it doesn't specify scenarios, prerequisites, or contrast with sibling tools like 'list_snapshots' or 'restore_snapshot' for backup workflows.

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/itshare4u/AgentKnowledgeMCP'

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