Skip to main content
Glama
mcpcap

mcpcap

by mcpcap

analyze_icmp_packets

Analyze ICMP packets in PCAP files to identify network issues and monitor connectivity. Use URL or local file paths for packet capture analysis.

Instructions

Analyze ICMP packets from a PCAP file and return comprehensive analysis results.

⚠️ FILE UPLOAD LIMITATION: This MCP tool cannot process files uploaded through Claude's web interface. Files must be accessible via URL or local file path.

SUPPORTED INPUT FORMATS:

  • Remote files: "https://example.com/capture.pcap"

  • Local files: "/absolute/path/to/capture.pcap"

UNSUPPORTED:

  • Files uploaded through Claude's file upload feature

  • Base64 file content

  • Relative file paths

Args: pcap_file: HTTP URL or absolute local file path to PCAP file

Returns: A structured dictionary containing ICMP packet analysis results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pcap_fileYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Primary MCP tool handler function for analyzing ICMP packets. Delegates to base analyze_packets for file handling.
    def analyze_icmp_packets(self, pcap_file: str) -> dict[str, Any]:
        """
        Analyze ICMP packets from a PCAP file and return comprehensive analysis results.
    
        ⚠️  FILE UPLOAD LIMITATION: This MCP tool cannot process files uploaded through
        Claude's web interface. Files must be accessible via URL or local file path.
    
        SUPPORTED INPUT FORMATS:
        - Remote files: "https://example.com/capture.pcap"
        - Local files: "/absolute/path/to/capture.pcap"
    
        UNSUPPORTED:
        - Files uploaded through Claude's file upload feature
        - Base64 file content
        - Relative file paths
    
        Args:
            pcap_file: HTTP URL or absolute local file path to PCAP file
    
        Returns:
            A structured dictionary containing ICMP packet analysis results
        """
        return self.analyze_packets(pcap_file)
  • Tool registration in MCPServer._register_tools method, specifically the line registering module.analyze_icmp_packets for the ICMP module.
    def _register_tools(self) -> None:
        """Register all available tools with the MCP server."""
        # Register tools for each loaded module
        for module_name, module in self.modules.items():
            if module_name == "dns":
                self.mcp.tool(module.analyze_dns_packets)
            elif module_name == "dhcp":
                self.mcp.tool(module.analyze_dhcp_packets)
            elif module_name == "icmp":
                self.mcp.tool(module.analyze_icmp_packets)
            elif module_name == "capinfos":
                self.mcp.tool(module.analyze_capinfos)
            elif module_name == "tcp":
                self.mcp.tool(module.analyze_tcp_connections)
                self.mcp.tool(module.analyze_tcp_anomalies)
                self.mcp.tool(module.analyze_tcp_retransmissions)
                self.mcp.tool(module.analyze_traffic_flow)
  • Core analysis logic: loads PCAP, filters ICMP packets, analyzes each, generates statistics.
    def _analyze_protocol_file(self, pcap_file: str) -> dict[str, Any]:
        """Perform the actual ICMP packet analysis on a local PCAP file."""
        try:
            packets = rdpcap(pcap_file)
            icmp_packets = [pkt for pkt in packets if pkt.haslayer(ICMP)]
    
            if not icmp_packets:
                return {
                    "file": pcap_file,
                    "total_packets": len(packets),
                    "icmp_packets_found": 0,
                    "message": "No ICMP packets found in this capture",
                }
    
            # Apply max_packets limit if specified
            packets_to_analyze = icmp_packets
            limited = False
            if self.config.max_packets and len(icmp_packets) > self.config.max_packets:
                packets_to_analyze = icmp_packets[: self.config.max_packets]
                limited = True
    
            packet_details = []
            for i, pkt in enumerate(packets_to_analyze, 1):
                packet_info = self._analyze_icmp_packet(pkt, i)
                packet_details.append(packet_info)
    
            # Generate statistics
            stats = self._generate_statistics(packet_details)
    
            result = {
                "file": pcap_file,
                "analysis_timestamp": datetime.now().isoformat(),
                "total_packets": len(packets),
                "icmp_packets_found": len(icmp_packets),
                "icmp_packets_analyzed": len(packet_details),
                "statistics": stats,
                "packets": packet_details,
            }
    
            if limited:
                result["note"] = (
                    f"Analysis limited to first {self.config.max_packets} ICMP packets due to --max-packets setting"
                )
    
            return result
    
        except Exception as e:
            return {
                "error": f"Error reading PCAP file '{pcap_file}': {str(e)}",
                "file": pcap_file,
            }
  • Base class method called by the handler to dispatch local/remote PCAP analysis.
    def analyze_packets(self, pcap_file: str) -> dict[str, Any]:
        """Analyze packets from a PCAP file (local or remote).
    
        Args:
            pcap_file: Path to local PCAP file or HTTP URL to remote PCAP file
    
        Returns:
            A structured dictionary containing packet analysis results
        """
        # Check if this is a remote URL or local file
        if pcap_file.startswith(("http://", "https://")):
            return self._handle_remote_analysis(pcap_file)
        else:
            return self._handle_local_analysis(pcap_file)
  • Per-packet analysis extracting IP/ICMP details, type/code mappings, etc.
    def _analyze_icmp_packet(self, packet, packet_num: int) -> dict[str, Any]:
        """Analyze a single ICMP packet and extract relevant information."""
        info = {
            "packet_number": packet_num,
            "timestamp": datetime.fromtimestamp(float(packet.time)).isoformat(),
        }
    
        # Basic IP information
        if packet.haslayer(IP):
            ip_layer = packet[IP]
            info.update(
                {
                    "src_ip": ip_layer.src,
                    "dst_ip": ip_layer.dst,
                    "ip_version": 4,
                    "ttl": ip_layer.ttl,
                    "packet_size": len(packet),
                }
            )
        elif packet.haslayer(IPv6):
            ipv6_layer = packet[IPv6]
            info.update(
                {
                    "src_ip": ipv6_layer.src,
                    "dst_ip": ipv6_layer.dst,
                    "ip_version": 6,
                    "hop_limit": ipv6_layer.hlim,
                    "packet_size": len(packet),
                }
            )
    
        # ICMP information
        if packet.haslayer(ICMP):
            icmp_layer = packet[ICMP]
    
            # Map ICMP types to human-readable names
            icmp_types = {
                0: "Echo Reply",
                3: "Destination Unreachable",
                4: "Source Quench",
                5: "Redirect",
                8: "Echo Request",
                11: "Time Exceeded",
                12: "Parameter Problem",
                13: "Timestamp Request",
                14: "Timestamp Reply",
                15: "Information Request",
                16: "Information Reply",
            }
    
            # Map destination unreachable codes
            dest_unreach_codes = {
                0: "Network Unreachable",
                1: "Host Unreachable",
                2: "Protocol Unreachable",
                3: "Port Unreachable",
                4: "Fragmentation Required",
                5: "Source Route Failed",
            }
    
            # Map time exceeded codes
            time_exceeded_codes = {
                0: "TTL Exceeded in Transit",
                1: "Fragment Reassembly Time Exceeded",
            }
    
            icmp_type = icmp_layer.type
            icmp_code = icmp_layer.code
    
            info.update(
                {
                    "icmp_type": icmp_type,
                    "icmp_code": icmp_code,
                    "icmp_type_name": icmp_types.get(
                        icmp_type, f"Unknown Type ({icmp_type})"
                    ),
                    "icmp_id": getattr(icmp_layer, "id", None),
                    "icmp_seq": getattr(icmp_layer, "seq", None),
                    "checksum": icmp_layer.chksum,
                }
            )
    
            # Add code descriptions for specific types
            if icmp_type == 3:  # Destination Unreachable
                info["icmp_code_name"] = dest_unreach_codes.get(
                    icmp_code, f"Unknown Code ({icmp_code})"
                )
            elif icmp_type == 11:  # Time Exceeded
                info["icmp_code_name"] = time_exceeded_codes.get(
                    icmp_code, f"Unknown Code ({icmp_code})"
                )
            else:
                info["icmp_code_name"] = f"Code {icmp_code}"
    
        return info
Behavior4/5

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

With no annotations provided, the description carries full burden and does well by disclosing critical behavioral constraints: the file upload limitation warning, supported/unsupported input formats, and that it returns structured analysis results. It doesn't mention performance characteristics, rate limits, or authentication needs, but provides substantial operational guidance.

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 (warning, supported formats, unsupported formats, args, returns) and front-loaded with the core purpose. Every sentence earns its place by providing essential operational information, though it could be slightly more concise in the format listings.

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

Completeness5/5

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

Given the tool's complexity (file processing with specific format requirements), no annotations, and the presence of an output schema (which handles return value documentation), the description is complete. It covers purpose, usage constraints, parameter requirements, and behavioral limitations—everything needed for effective tool selection and invocation.

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?

With 0% schema description coverage (schema only shows pcap_file is a required string), the description fully compensates by explaining parameter semantics: it specifies pcap_file must be 'HTTP URL or absolute local file path to PCAP file' and provides detailed format requirements with examples and exclusions, adding significant value beyond the bare schema.

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 tool's purpose: 'Analyze ICMP packets from a PCAP file and return comprehensive analysis results.' It specifies the verb ('analyze'), resource ('ICMP packets from a PCAP file'), and distinguishes from siblings by focusing specifically on ICMP protocol analysis rather than other protocols like DHCP, DNS, or TCP.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool versus alternatives through its file format requirements and sibling tool context. It clearly states what input formats are supported (URLs, absolute local paths) and unsupported (web uploads, base64, relative paths), and the sibling tools list shows this is specifically for ICMP analysis while others handle different protocols.

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/mcpcap/mcpcap'

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