npm package: @modular-intelligence/nmap
Description: MCP server wrapping nmap for network scanning
Latest version: 1.0.2

# Nmap MCP Server

A comprehensive network scanning and host discovery service that integrates nmap and masscan command-line tools through the Model Context Protocol. This MCP (Model Context Protocol) server enables Claude to perform network reconnaissance, port scanning, service detection, OS fingerprinting, and vulnerability scanning.

## Overview

This server provides access to powerful network scanning capabilities through a unified interface:

- **Nmap** - Industry-standard network scanner for port discovery, service identification, OS detection, and NSE scripting
- **Masscan** - High-speed port scanner optimized for scanning large network ranges

Perfect for network security assessments, incident response, vulnerability research, network mapping, and security auditing.

## Tools

| Tool | CLI Tool | Description |
|------|----------|-------------|
| `nmap_scan_ports` | Nmap | Port scanning with TCP connect, SYN, UDP, or ACK scan types |
| `nmap_discover_hosts` | Nmap | Host discovery using ping, ARP, TCP, or UDP probes |
| `nmap_detect_services` | Nmap | Service version detection and optional NSE default scripts |
| `nmap_run_scripts` | Nmap | Execute Nmap Scripting Engine (NSE) scripts for enumeration and vulnerability detection |
| `nmap_os_detect` | Nmap | Operating system fingerprinting via TCP/IP stack analysis |
| `masscan_scan` | Masscan | High-speed port scanning across large CIDR ranges |

### Nmap Port Scanning

Scan targets for open, closed, and filtered ports using various scan types.

**Input Parameters:**
```typescript
{
  target: string           // Host, IP, CIDR, or comma-separated list of targets
  ports: string           // Port specification: "22,80,443", "1-1024", "U:53,T:25" (optional)
  scan_type: string       // "tcp_connect" (default, no root), "tcp_syn", "udp", or "tcp_ack" (require root)
  top_ports: number       // Scan N most common ports (1-65535, optional)
  timing: number          // Timing template: 0-5 (paranoid to insane, default: 3)
  skip_host_discovery: boolean  // Skip host discovery phase (default: false)
  timeout: number         // Max scan duration in seconds (10-600, default: 120)
}
```

**Example Request:**
```json
{
  "target": "192.168.1.0/24",
  "ports": "22,80,443",
  "scan_type": "tcp_connect",
  "timing": 3,
  "timeout": 120
}
```

**Example Output:**
```json
{
  "scan": {
    "scanner": "nmap",
    "version": "7.80",
    "args": "nmap -sT -p 22,80,443 -T3 192.168.1.0/24",
    "start_time": "Mon Jan 15 10:30:45 2024",
    "scan_types": [
      {
        "protocol": "tcp",
        "flags": "syn",
        "services": "22,80,443"
      }
    ]
  },
  "hosts": [
    {
      "status": "up",
      "addresses": [
        {
          "addr": "192.168.1.100",
          "type": "ipv4"
        }
      ],
      "hostnames": [
        {
          "name": "router.local",
          "type": "PTR"
        }
      ],
      "ports": [
        {
          "protocol": "tcp",
          "port_id": 22,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "ssh",
            "product": "OpenSSH",
            "version": "7.4",
            "confidence": 10,
            "method": "table",
            "cpes": []
          },
          "scripts": []
        },
        {
          "protocol": "tcp",
          "port_id": 80,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "http",
            "product": "Apache httpd",
            "version": "2.4.6",
            "confidence": 10,
            "method": "table",
            "cpes": []
          },
          "scripts": []
        }
      ],
      "os_matches": [],
      "trace": []
    }
  ],
  "stats": {
    "elapsed_seconds": 15,
    "hosts_up": 1,
    "hosts_down": 254,
    "hosts_total": 255,
    "exit_status": "success"
  },
  "warnings": []
}
```

### Nmap Host Discovery

Discover live hosts on a network without performing port scans.

**Input Parameters:**
```typescript
{
  target: string              // Host, IP, CIDR, or comma-separated list of targets
  technique: string           // "ping" (default), "arp", "tcp_syn", "tcp_ack", or "udp"
  ports: string              // Ports for TCP/UDP probes (e.g., "22,80,443", optional)
  traceroute: boolean        // Enable traceroute (default: false)
  dns_resolve: string        // DNS resolution: "always", "never", or "default" (default: "default")
  timeout: number            // Max scan duration in seconds (10-600, default: 120)
}
```

**Example Request:**
```json
{
  "target": "10.0.0.0/24",
  "technique": "ping",
  "traceroute": false,
  "dns_resolve": "default",
  "timeout": 60
}
```

**Example Output:**
```json
{
  "scan": {
    "scanner": "nmap",
    "version": "7.80",
    "args": "nmap -sn -PE -PP 10.0.0.0/24",
    "start_time": "Mon Jan 15 10:45:20 2024",
    "scan_types": [
      {
        "protocol": "tcp",
        "flags": "ping",
        "services": ""
      }
    ]
  },
  "hosts": [
    {
      "status": "up",
      "addresses": [
        {
          "addr": "10.0.0.5",
          "type": "ipv4"
        }
      ],
      "hostnames": [
        {
          "name": "server1.example.com",
          "type": "PTR"
        }
      ],
      "ports": [],
      "os_matches": [],
      "trace": []
    },
    {
      "status": "up",
      "addresses": [
        {
          "addr": "10.0.0.10",
          "type": "ipv4"
        }
      ],
      "hostnames": [
        {
          "name": "server2.example.com",
          "type": "PTR"
        }
      ],
      "ports": [],
      "os_matches": [],
      "trace": []
    }
  ],
  "stats": {
    "elapsed_seconds": 8,
    "hosts_up": 2,
    "hosts_down": 253,
    "hosts_total": 255,
    "exit_status": "success"
  },
  "warnings": []
}
```

### Nmap Service Detection

Probe open ports to identify running services and their versions.

**Input Parameters:**
```typescript
{
  target: string              // Host, IP, CIDR, or comma-separated list of targets
  ports: string              // Port specification (required)
  intensity: number          // Version detection intensity 0-9 (default: 7)
  default_scripts: boolean   // Run default NSE scripts (-sC) (default: false)
  timing: number             // Timing template: 0-5 (default: 3)
  timeout: number            // Max scan duration in seconds (10-600, default: 180)
}
```

**Example Request:**
```json
{
  "target": "192.168.1.100",
  "ports": "22,80,443,3306",
  "intensity": 7,
  "default_scripts": true,
  "timing": 3,
  "timeout": 180
}
```

**Example Output:**
```json
{
  "scan": {
    "scanner": "nmap",
    "version": "7.80",
    "args": "nmap -sV --version-intensity 7 -sC -p 22,80,443,3306 -T3 192.168.1.100",
    "start_time": "Mon Jan 15 11:00:00 2024",
    "scan_types": [
      {
        "protocol": "tcp",
        "flags": "syn",
        "services": "22,80,443,3306"
      }
    ]
  },
  "hosts": [
    {
      "status": "up",
      "addresses": [
        {
          "addr": "192.168.1.100",
          "type": "ipv4"
        }
      ],
      "hostnames": [
        {
          "name": "webserver.example.com",
          "type": "PTR"
        }
      ],
      "ports": [
        {
          "protocol": "tcp",
          "port_id": 22,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "ssh",
            "product": "OpenSSH",
            "version": "7.4p1",
            "extra_info": "Debian",
            "confidence": 10,
            "method": "probed",
            "cpes": [
              "cpe:/a:openbsd:openssh:7.4p1"
            ]
          },
          "scripts": [
            {
              "id": "ssh-hostkey",
              "output": "1024 aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99 (RSA)\nKey type: rsa\nKey bits: 2048",
              "data": {}
            }
          ]
        },
        {
          "protocol": "tcp",
          "port_id": 80,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "http",
            "product": "Apache httpd",
            "version": "2.4.41",
            "extra_info": "Ubuntu",
            "confidence": 10,
            "method": "probed",
            "cpes": [
              "cpe:/a:apache:http_server:2.4.41"
            ]
          },
          "scripts": [
            {
              "id": "http-title",
              "output": "Did not follow redirect to https://webserver.example.com/",
              "data": {}
            }
          ]
        },
        {
          "protocol": "tcp",
          "port_id": 443,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "https",
            "product": "Apache httpd",
            "version": "2.4.41",
            "confidence": 10,
            "method": "probed",
            "cpes": []
          },
          "scripts": []
        },
        {
          "protocol": "tcp",
          "port_id": 3306,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "mysql",
            "product": "MySQL",
            "version": "5.7.32",
            "confidence": 10,
            "method": "probed",
            "cpes": [
              "cpe:/a:mysql:mysql:5.7.32"
            ]
          },
          "scripts": []
        }
      ],
      "os_matches": [],
      "trace": []
    }
  ],
  "stats": {
    "elapsed_seconds": 25,
    "hosts_up": 1,
    "hosts_down": 0,
    "hosts_total": 1,
    "exit_status": "success"
  },
  "warnings": []
}
```

### Nmap Run Scripts

Execute Nmap Scripting Engine (NSE) scripts for vulnerability detection, enumeration, and exploitation testing.

**Input Parameters:**
```typescript
{
  target: string              // Host, IP, CIDR, or comma-separated list of targets
  scripts: string            // NSE script spec: "http-title", "vuln", "default", "smb-*", etc.
  script_args: string        // Script arguments as key=value pairs (optional)
  ports: string              // Port specification (optional)
  timing: number             // Timing template: 0-5 (default: 3)
  timeout: number            // Max scan duration in seconds (30-600, default: 300)
}
```

**Example Request:**
```json
{
  "target": "192.168.1.100",
  "scripts": "vuln",
  "ports": "22,80,443",
  "timing": 3,
  "timeout": 300
}
```

**Example Output:**
```json
{
  "scan": {
    "scanner": "nmap",
    "version": "7.80",
    "args": "nmap --script vuln -p 22,80,443 -T3 192.168.1.100",
    "start_time": "Mon Jan 15 11:30:00 2024",
    "scan_types": [
      {
        "protocol": "tcp",
        "flags": "syn",
        "services": "22,80,443"
      }
    ]
  },
  "hosts": [
    {
      "status": "up",
      "addresses": [
        {
          "addr": "192.168.1.100",
          "type": "ipv4"
        }
      ],
      "hostnames": [
        {
          "name": "vulnerable-server.example.com",
          "type": "PTR"
        }
      ],
      "ports": [
        {
          "protocol": "tcp",
          "port_id": 80,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "http",
            "confidence": 0,
            "method": "",
            "cpes": []
          },
          "scripts": [
            {
              "id": "http-server-header",
              "output": "Apache/2.4.41 (Ubuntu)",
              "data": {}
            },
            {
              "id": "ssl-known-key",
              "output": "Host key fingerprint ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90\nThis key is known to be used in:\n  - CVE-2014-0160 (Heartbleed)",
              "data": {
                "CVE": "CVE-2014-0160",
                "Type": "Information Leak",
                "Description": "Heartbleed vulnerability in OpenSSL"
              }
            }
          ]
        }
      ],
      "os_matches": [],
      "trace": []
    }
  ],
  "stats": {
    "elapsed_seconds": 45,
    "hosts_up": 1,
    "hosts_down": 0,
    "hosts_total": 1,
    "exit_status": "success"
  },
  "warnings": []
}
```

### Nmap OS Detection

Fingerprint remote operating systems via TCP/IP stack analysis (requires root privileges).

**Input Parameters:**
```typescript
{
  target: string              // Host, IP, CIDR, or comma-separated list of targets
  aggressive_guess: boolean   // Use aggressive OS guessing (--osscan-guess) (default: false)
  limit_detection: boolean    // Only detect on promising targets (--osscan-limit) (default: true)
  ports: string              // Port specification (optional)
  timeout: number            // Max scan duration in seconds (30-600, default: 180)
}
```

**Example Request:**
```json
{
  "target": "192.168.1.100",
  "aggressive_guess": true,
  "limit_detection": true,
  "ports": "22,80,443",
  "timeout": 180
}
```

**Example Output:**
```json
{
  "scan": {
    "scanner": "nmap",
    "version": "7.80",
    "args": "nmap -O --osscan-guess --osscan-limit -p 22,80,443 192.168.1.100",
    "start_time": "Mon Jan 15 12:00:00 2024",
    "scan_types": [
      {
        "protocol": "tcp",
        "flags": "syn",
        "services": "22,80,443"
      }
    ]
  },
  "hosts": [
    {
      "status": "up",
      "addresses": [
        {
          "addr": "192.168.1.100",
          "type": "ipv4"
        }
      ],
      "hostnames": [
        {
          "name": "ubuntu-server.example.com",
          "type": "PTR"
        }
      ],
      "ports": [
        {
          "protocol": "tcp",
          "port_id": 22,
          "state": "open",
          "state_reason": "syn-ack",
          "service": {
            "name": "ssh",
            "confidence": 0,
            "method": "",
            "cpes": []
          },
          "scripts": []
        }
      ],
      "os_matches": [
        {
          "name": "Linux 4.15 - 5.6",
          "accuracy": 95,
          "os_classes": [
            {
              "type": "general purpose",
              "vendor": "Linux",
              "os_family": "Linux",
              "os_generation": "4.X|5.X",
              "accuracy": 95,
              "cpes": [
                "cpe:/o:linux:linux_kernel:4.15",
                "cpe:/o:linux:linux_kernel:5.6"
              ]
            }
          ]
        },
        {
          "name": "Ubuntu 16.04 - 20.04 (Linux 4.4 - 5.4)",
          "accuracy": 92,
          "os_classes": [
            {
              "type": "general purpose",
              "vendor": "Canonical",
              "os_family": "Linux",
              "os_generation": "16.04|18.04|20.04",
              "accuracy": 92,
              "cpes": [
                "cpe:/o:canonical:ubuntu_linux:16.04",
                "cpe:/o:canonical:ubuntu_linux:18.04",
                "cpe:/o:canonical:ubuntu_linux:20.04"
              ]
            }
          ]
        }
      ],
      "trace": []
    }
  ],
  "stats": {
    "elapsed_seconds": 60,
    "hosts_up": 1,
    "hosts_down": 0,
    "hosts_total": 1,
    "exit_status": "success"
  },
  "warnings": []
}
```

### Masscan High-Speed Port Scanning

Perform high-speed port scanning across large network ranges using masscan.

**Input Parameters:**
```typescript
{
  target: string      // Target IP, CIDR range, or hostname (e.g., "192.168.1.0/24", "10.0.0.0/16")
  ports: string       // Port specification: "80,443", "1-1000", "0-65535"
  rate: number        // Packets per second (100-100000, default: 1000)
  timeout: number     // Timeout in seconds (10-600, default: 120)
}
```

**Example Request:**
```json
{
  "target": "192.168.1.0/24",
  "ports": "22,80,443,8080",
  "rate": 5000,
  "timeout": 120
}
```

**Example Output:**
```json
{
  "target": "192.168.1.0/24",
  "ports": "22,80,443,8080",
  "rate": 5000,
  "total_open_ports": 5,
  "total_hosts": 3,
  "hosts": [
    {
      "ip": "192.168.1.1",
      "port_count": 2,
      "open_ports": [
        {
          "port": 22,
          "protocol": "tcp",
          "state": "open"
        },
        {
          "port": 443,
          "protocol": "tcp",
          "state": "open"
        }
      ]
    },
    {
      "ip": "192.168.1.100",
      "port_count": 2,
      "open_ports": [
        {
          "port": 80,
          "protocol": "tcp",
          "state": "open"
        },
        {
          "port": 443,
          "protocol": "tcp",
          "state": "open"
        }
      ]
    },
    {
      "ip": "192.168.1.200",
      "port_count": 1,
      "open_ports": [
        {
          "port": 8080,
          "protocol": "tcp",
          "state": "open"
        }
      ]
    }
  ]
}
```

## Configuration

### Environment Variables

This server requires the nmap and masscan command-line tools to be installed. No API keys are required.

```bash
export PATH="/opt/homebrew/bin:$PATH"  # macOS Homebrew path
# or
export PATH="/usr/bin:$PATH"           # Linux standard path
```

### Binary Locations

The server expects nmap to be located at `/opt/homebrew/bin/nmap` (macOS Homebrew default). For other systems, modify the `NMAP_PATH` in `src/nmap-executor.ts` to match your installation.

## Prerequisites

- **Nmap** - Network scanning utility
  - Installation: `brew install nmap` (macOS) or `apt-get install nmap` (Linux)
  - Website: https://nmap.org/
  - Documentation: https://nmap.org/book/

- **Masscan** (optional) - High-speed port scanner
  - Installation: `brew install masscan` (macOS) or `apt-get install masscan` (Linux)
  - Website: https://github.com/robertdavis60/masscan
  - Documentation: https://github.com/robertdavis60/masscan/wiki

- **Root/Sudo Privileges** (for some scan types)
  - TCP SYN scans (-sS)
  - UDP scans (-sU)
  - TCP ACK scans (-sA)
  - OS detection (-O)
  - Some NSE scripts

## Installation

### Prerequisites

- Bun runtime (version 1.x or later)
- Node.js 18+ (alternative runtime)
- Nmap installed and accessible
- Masscan installed (optional, for high-speed scanning)

### Steps

1. Clone or download this repository:
```bash
git clone <repo-url>
cd nmap
```

2. Install dependencies:
```bash
bun install
```

3. Build the project:
```bash
bun run build
```

4. Verify nmap is installed:
```bash
which nmap
nmap --version
```

5. Run the server:
```bash
bun run start
```

The server will start listening on stdio transport.

## Usage

### Running the Server

Start the server with Bun:

```bash
bun run src/index.ts
```

The server implements the Model Context Protocol (MCP) and communicates via stdio transport. It can be integrated with Claude or other MCP clients.

### Claude Desktop Configuration

Add the server to your Claude Desktop configuration at `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "nmap": {
      "command": "bun",
      "args": [
        "run",
        "/path/to/nmap/src/index.ts"
      ]
    }
  }
}
```

### Claude Code MCP Settings

Configure the server in Claude Code's MCP settings (typically in `.mcp.json` or via settings UI):

```json
{
  "servers": {
    "nmap": {
      "transport": "stdio",
      "command": "bun",
      "args": ["run", "/path/to/nmap/src/index.ts"]
    }
  }
}
```

### Example Usage in Claude

Once configured, you can use the tools directly in conversations with Claude:

**Request:**
"Scan 192.168.1.0/24 for the top 20 common ports"

**Claude will call:**
```json
{
  "tool": "nmap_scan_ports",
  "input": {
    "target": "192.168.1.0/24",
    "top_ports": 20,
    "timing": 3
  }
}
```

**Request:**
"Discover live hosts on the 10.0.0.0/24 network using ARP probes"

**Claude will call:**
```json
{
  "tool": "nmap_discover_hosts",
  "input": {
    "target": "10.0.0.0/24",
    "technique": "arp"
  }
}
```

**Request:**
"Detect services and versions on 192.168.1.100 ports 22, 80, 443"

**Claude will call:**
```json
{
  "tool": "nmap_detect_services",
  "input": {
    "target": "192.168.1.100",
    "ports": "22,80,443",
    "intensity": 7,
    "default_scripts": true
  }
}
```

**Request:**
"Scan 192.168.1.100 for known vulnerabilities"

**Claude will call:**
```json
{
  "tool": "nmap_run_scripts",
  "input": {
    "target": "192.168.1.100",
    "scripts": "vuln"
  }
}
```

**Request:**
"Quickly scan the entire 192.168.0.0/16 network for open port 443"

**Claude will call:**
```json
{
  "tool": "masscan_scan",
  "input": {
    "target": "192.168.0.0/16",
    "ports": "443",
    "rate": 10000
  }
}
```

## Security

This server implements comprehensive input validation and security measures to prevent injection attacks and misuse:

### Input Validation

**Target Validation**
- Accepts hostnames, IPv4 addresses, CIDR ranges, and comma-separated lists
- Valid characters: alphanumeric, dots, colons, hyphens, slashes, brackets, spaces
- Rejects blocked options: `-iR`, `-iL`, `--exclude-file`, `--excludefile`
- CIDR prefix validation: minimum /16 to prevent overly broad network scans
- Prevents command injection via special characters

**Port Specification Validation**
- Accepts port numbers, ranges, and protocol prefixes (T: for TCP, U: for UDP)
- Valid characters: digits, commas, hyphens, T:, U:, and spaces
- Examples: "22,80,443", "1-1024", "T:22,80 U:53"
- Rejects special characters and shell metacharacters

**Script Validation**
- Accepts NSE script names and categories
- Valid characters: alphanumeric, commas, hyphens, underscores, asterisks, spaces
- Examples: "vuln", "default", "http-*", "smb-os-discovery"
- Rejects shell metacharacters

**Script Arguments Validation**
- Accepts key=value pairs for NSE script arguments
- Valid characters: alphanumeric, dots, commas, equals, underscores, hyphens, slashes, colons, spaces
- Examples: "username=admin", "password=test123"
- Rejects injection attempts

### Privilege Requirements

- **TCP Connect Scans** - No privileges required
- **TCP SYN Scans** - Requires root/sudo
- **UDP Scans** - Requires root/sudo
- **TCP ACK Scans** - Requires root/sudo
- **OS Detection** - Requires root/sudo
- All other tools require appropriate permissions for raw socket access

### What Gets Blocked

The server rejects:
- Invalid target formats (non-domain, non-IP strings)
- Overly broad CIDR ranges (prefix < /16)
- Blocked nmap options (file input, host lists, exclusion files)
- Invalid port specifications (non-numeric, wrong format)
- Shell metacharacters in inputs (`;`, `&`, `|`, backticks, `$`, `()`, `{}`)
- Missing or invalid parameters
- Oversized inputs

### Error Handling

- Invalid inputs return descriptive error messages
- Missing root privileges trigger helpful configuration messages
- Command execution errors are caught and reported
- Network timeouts are handled gracefully
- Scan failures provide diagnostic information

## License

ISC License - see LICENSE file for details