Nmap Scanner Server

安全与合规

by sideffect263

Enable network scanning by initiating Nmap scans and retrieving structured JSON results through a simple HTTP API. Manage scan tasks with real-time status updates and detailed parsed outputs. Simplify network reconnaissance workflows with automated and accessible scanning capabilities.

什么是 Nmap Scanner Server

Enable network scanning by initiating Nmap scans and retrieving structured JSON results through a simple HTTP API. Manage scan tasks with real-time status updates and detailed parsed outputs. Simplify network reconnaissance workflows with automated and accessible scanning capabilities.

README

Nmap MCP Server (Smithery SDK)

This project implements an MCP-compliant (Model Context Protocol) server using the Smithery SDK. It wraps the Nmap network scanner, exposing its functionality as callable tools within the MCP framework.

Features

  • MCP Standard Endpoint (/mcp): Interacts with the server using JSON-RPC 2.0 requests.
  • nmapScan Tool: Initiates an Nmap scan on a specified target with configurable flags. Returns detailed scan results, including parsed XML output.
  • getInfo Tool: Provides basic information about the Nmap service and its capabilities.
  • Input validation for targets and Nmap flags to enhance security.

Prerequisites

  • Node.js (v16.x or later recommended)
  • Nmap installed and available in your system's PATH.

Installation

  1. Clone the repository (or download the source code).
  2. Navigate to the project directory:
    bash
    cd your-project-directory
    
  3. Install dependencies:
    bash
    npm install
    

Running the Server

To start the server, run:

bash
npm start

By default, the server will listen on http://localhost:5001. You can set the PORT environment variable to use a different port.

Interacting with the Server (MCP)

All interactions with the server are done via the /mcp endpoint using JSON-RPC 2.0. You will send POST requests with a Content-Type: application/json header.

Calling the nmapScan Tool

To initiate an Nmap scan:

Request Body (JSON):

json
{
  "jsonrpc": "2.0",
  "id": 1, // Or any unique request ID
  "method": "tools/call",
  "params": {
    "name": "nmapScan",
    "arguments": {
      "target": "scanme.nmap.org",
      "flags": "-A -T4" // Optional, defaults to "-T4 -p 1-1000"
    }
  }
}

Example using cURL:

bash
curl -X POST http://localhost:5001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "nmapScan",
      "arguments": {
        "target": "scanme.nmap.org",
        "flags": "-A"
      }
    }
  }'

Expected Response Structure (Success):

The server will respond with the results of the Nmap scan. The content array will contain a text object with a summary and the full JSON-parsed Nmap XML output.

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Nmap Scan Results for scanme.nmap.org\n\nScan started: ...\n... (summary of open ports) ...\nScan completed: ...\n\nFull XML Output:\n{\n  \"nmaprun\": { ... }\n}"
      }
    ]
  }
}

If the scan fails or inputs are invalid, the text field will contain an error message.

Calling the getInfo Tool

To get information about the service:

Request Body (JSON):

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "getInfo",
    "arguments": {}
  }
}

Example using cURL:

bash
curl -X POST http://localhost:5001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "getInfo",
      "arguments": {}
    }
  }'

Expected Response Structure (Success):

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Nmap Service Information:\n- Service: Network scanning using Nmap\n- Version: 1.0.0\n- Available Tools: nmapScan, getInfo\n- Session ID: N/A\n- Supported Targets: Domain names, IP addresses, CIDR notation\n- Security: Input validation and command sanitization enabled"
      }
    ]
  }
}

Deployment on Smithery

To deploy this server on Smithery, you will typically need to:

  1. Ensure Nmap is available in the Smithery execution environment. This might involve custom Docker images or buildpacks if Nmap isn't pre-installed.
  2. Define the startup command: Smithery will need to know how to start the application (e.g., npm start).
  3. Port configuration: Smithery will expose the application, usually handling port mapping. Ensure the application listens on the port Smithery expects (often configured via the PORT environment variable, which this server supports via the process.env.PORT || 5001 pattern).
  4. Package the application: This usually means providing the source code and package.json (and package-lock.json). Smithery will then build the application, installing dependencies.

Refer to the Smithery documentation for specific deployment instructions and how to configure services that adhere to the Model Context Protocol.

Example MCP Client

Below is an example of how to create a client to interact with this Nmap MCP server. You'll need to have the @modelcontextprotocol/sdk and @smithery/sdk packages installed in your client project.

Save the following code as nmap_mcp_client_example.js:

javascript
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { createSmitheryUrl } from "@smithery/sdk/shared/config.js";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

// Ensure you have your Smithery API key for the server in an environment variable
const SMITHERY_API_KEY = process.env.SMITHERY_NMAP_API_KEY || "your-smithery-api-key-here"; // Replace with your actual key or ensure env var is set
const NMAP_SERVER_URL = "https://server.smithery.ai/@sideffect263/nmap-mcp-server"; // Replace with your server URL if different

let clientInstance;
let nmapScanTool;
let getInfoTool;

async function initializeNmapClient() {
  if (clientInstance) {
    console.log("Nmap MCP Client already initialized.");
    return clientInstance;
  }

  console.log("Initializing Nmap MCP Client...");

  try {
    const config = {}; // Add any specific config for Smithery if needed
    const serverUrl = createSmitheryUrl(
      NMAP_SERVER_URL,
      { config, apiKey: SMITHERY_API_KEY }
    );

    const transport = new StreamableHTTPClientTransport(serverUrl);

    clientInstance = new Client({
      name: "ExampleNmapClient",
      version: "1.0.0",
    });

    console.log("Connecting to Nmap MCP server...");
    await clientInstance.connect(transport);
    console.log("Successfully connected to Nmap MCP server.");

    const toolsResponse = await clientInstance.listTools();
  
    if (toolsResponse && toolsResponse.tools && Array.isArray(toolsResponse.tools)) {
      console.log(`Available tools: ${toolsResponse.tools.map((t) => t.name).join(", ")}`);
      nmapScanTool = toolsResponse.tools.find(tool => tool.name === 'nmapScan');
      getInfoTool = toolsResponse.tools.find(tool => tool.name === 'getInfo');
    } else {
      throw new Error("Could not list tools from the server.");
    }

    if (!nmapScanTool) {
      throw new Error("Nmap tool ('nmapScan') not found on the MCP server.");
    }
    console.log(`Found Nmap tool: ${nmapScanTool.name}`);

    if (getInfoTool) {
      console.log(`Found GetInfo tool: ${getInfoTool.name}`);
    } else {
      console.warn("GetInfo tool ('getInfo') not found. This might be optional.");
    }
  
    return clientInstance;
  } catch (error) {
    console.error("Failed to initialize Nmap MCP client:", error);
    clientInstance = null; // Reset on failure
    nmapScanTool = null;
    getInfoTool = null;
    throw error;
  }
}

/**
 * Invokes the 'nmapScan' tool on the MCP server.
 * @param {Object} params - Parameters for the Nmap tool.
 * @param {string} params.target - The target IP, hostname, or CIDR.
 * @param {string} params.flags - Nmap flags as a single string (e.g., "-A -T4").
 * @returns {Promise<Object>} - The result from the 'nmapScan' tool.
 */
async function invokeNmapScan(params) {
  if (!clientInstance || !nmapScanTool) {
    console.log("Client not ready. Initializing...");
    await initializeNmapClient();
    if (!clientInstance || !nmapScanTool) {
      throw new Error("Nmap MCP client is not initialized or nmapScan tool not found.");
    }
  }

  const toolInput = {
    target: params.target,
    flags: params.flags 
  };
  console.log(\`Invoking Nmap tool "\${nmapScanTool.name}" with params:\`, toolInput);

  try {
    const result = await clientInstance.callTool({
      name: nmapScanTool.name,
      arguments: toolInput
    });
    console.log("'nmapScan' tool invocation successful. Result:", JSON.stringify(result, null, 2));
    return result;
  } catch (error) {
    console.error(\`Error invoking 'nmapScan' tool for target \${params.target}:\`, error);
    throw error;
  }
}

/**
 * Invokes the 'getInfo' tool on the MCP server.
 * @returns {Promise<Object>} - The result from the 'getInfo' tool.
 */
async function invokeGetInfo() {
  if (!clientInstance || !getInfoTool) {
    console.log("Client or getInfo tool not ready. Initializing...");
    await initializeNmapClient();
    if (!clientInstance || !getInfoTool) {
      throw new Error("Nmap MCP client is not initialized or getInfo tool not found.");
    }
  }
  
  console.log(\`Invoking GetInfo tool "\${getInfoTool.name}"\`);
  try {
    const result = await clientInstance.callTool({
      name: getInfoTool.name,
      arguments: {} // getInfo usually takes no arguments
    });
    console.log("'getInfo' tool invocation successful. Result:", JSON.stringify(result, null, 2));
    return result;
  } catch (error) {
    console.error("Error invoking 'getInfo' tool:", error);
    throw error;
  }
}


// --- Example Usage ---
async function main() {
  try {
    await initializeNmapClient();

    // Example: Get server info
    console.log("\\n--- Calling getInfo ---");
    const info = await invokeGetInfo();
    if (info && info.content && info.content[0] && info.content[0].text) {
        console.log("Server Info:", info.content[0].text);
    }


    // Example: Perform an Nmap scan
    console.log("\\n--- Calling nmapScan ---");
    const scanParams = {
      target: "scanme.nmap.org", // A safe target for testing
      flags: "-T4 -F" // Example flags: Fast scan, default timing
    };
    const scanResult = await invokeNmapScan(scanParams);
    if (scanResult && scanResult.content && scanResult.content[0] && scanResult.content[0].text) {
        console.log(\`Scan results for \${scanParams.target}:\`, scanResult.content[0].text);
    }

  } catch (error) {
    console.error("\\n--- Example Script Failed ---");
    console.error("An error occurred:", error.message);
  } finally {
    if (clientInstance) {
      console.log("\\nDisconnecting client...");
      await clientInstance.disconnect();
      console.log("Client disconnected.");
    }
  }
}

// Run the example
main();

export { initializeNmapClient, invokeNmapScan, invokeGetInfo };

To run this example client:

  1. Ensure you have Node.js installed.
  2. Create a new directory for your client project.
  3. Inside this directory, run npm init -y to create a package.json file.
  4. Install the necessary SDKs:
    bash
    npm install @modelcontextprotocol/sdk @smithery/sdk
    
  5. Save the code above as nmap_mcp_client_example.js in this directory.
  6. Modify the SMITHERY_NMAP_API_KEY and NMAP_SERVER_URL constants in the script with your actual Smithery API key and the URL of your deployed Nmap MCP server.
  7. If your package.json doesn't already have "type": "module", add it or change the import/export syntax to CommonJS (require/module.exports). For ES Modules (as written), add:
    json
    // package.json
    {
      // ... other properties
      "type": "module" 
    }
    
  8. Run the client:
    bash
    node nmap_mcp_client_example.js
    

This client will connect to your Nmap MCP server, list available tools, call getInfo for server information, and then call nmapScan to perform a scan on scanme.nmap.org.

常见问题

Nmap Scanner Server 是什么?

Enable network scanning by initiating Nmap scans and retrieving structured JSON results through a simple HTTP API. Manage scan tasks with real-time status updates and detailed parsed outputs. Simplify network reconnaissance workflows with automated and accessible scanning capabilities.

相关 Skills

安全专家

by alirezarezvani

Universal
热门

覆盖威胁建模、漏洞评估、安全架构设计、代码审计与渗透测试,内置 STRIDE、OWASP、加密模式和安全扫描流程,适合系统设计评审与上线前安全排查。

安全专家把威胁建模、漏洞分析到渗透测试串成一套流程,内置 STRIDE 与 OWASP 指南,做安全设计和排查更省心。

安全与合规
未扫描23.8k

安全运营

by alirezarezvani

Universal
热门

覆盖应用安全、漏洞管理与合规审计,支持代码/依赖扫描、CVE 评估、Secrets 检测和安全自动化,适合做安全基线落地、漏洞响应、审计检查与安全开发治理。

应用安全、漏洞管理和合规检查一套打通,还能自动化扫描与响应,帮团队更早发现并收敛风险。

安全与合规
未扫描23.8k

安全审计

by alirezarezvani

Universal
热门

安装前审计 Claude Code Skill 的代码执行、Prompt 注入和依赖供应链风险,支持本地目录或 Git 仓库扫描,输出 PASS/WARN/FAIL 结论及修复建议

把代码审查、漏洞扫描和合规检查串成一条线,帮团队更早发现风险,做安全治理更省心。

安全与合规
未扫描23.8k

相关 MCP Server

搜索和分析 Sentry 错误报告,辅助调试。

把零散的 Sentry 错误报告变成可检索线索,帮你在海量报错里更快定位线上故障,排障调试明显省时。

安全与合规
805

为 AI agents 提供安全层:拦截 prompt injection、识别伪造 packages,并扫描漏洞风险。

给 AI Agent 补上关键安全层,能拦截 prompt 注入、识别伪造包并扫描漏洞风险,把防护前置更省心。

安全与合规
119

强化安全性的 NotebookLM MCP,集成 post-quantum encryption,提升数据防护能力。

安全与合规
77

评论