port_check
Check if a TCP port is open on a host to test network connectivity.
Instructions
Check whether a single TCP port is open on a host.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | ||
| port | Yes | ||
| timeout | No |
Implementation Reference
- src/sounding/server.py:222-238 (handler)The core handler for the port_check tool. It uses @mcp.tool() decorator to register the tool, validates the host and port, then attempts an asynchronous TCP connection. Returns {'state': 'open'} on success or {'state': 'closed'} on OSError/Timeout.
@mcp.tool() async def port_check(host: str, port: int, timeout: int = 3) -> dict: """Check whether a single TCP port is open on a host.""" host = validate_host(host) if not validate_port(port): raise ValueError(f"Invalid port: {port}") try: reader, writer = await asyncio.wait_for( asyncio.open_connection(host, port), timeout=timeout, ) writer.close() await writer.wait_closed() return {"host": host, "port": port, "state": "open"} except (OSError, asyncio.TimeoutError): return {"host": host, "port": port, "state": "closed"} - src/sounding/server.py:222-223 (registration)The @mcp.tool() decorator registers port_check as an MCP tool on the FastMCP instance.
@mcp.tool() async def port_check(host: str, port: int, timeout: int = 3) -> dict: - src/sounding/validators.py:101-143 (helper)Validates the host parameter - strips whitespace, rejects shell meta-characters, validates IP addresses and hostnames, and optionally checks for internal/SSRF.
def validate_host(host: str, *, allow_internal: bool = True) -> str: """Validate a hostname or IP address. Args: host: The hostname or IP to validate. allow_internal: If False, reject internal/private/loopback IPs and hostnames that resolve to them (SSRF protection). Defaults to True since tools like ping and traceroute legitimately target internal networks. Returns the cleaned host string. Raises ``ValueError`` on anything suspicious. """ host = host.strip() if not host: raise ValueError("Host must not be empty") if _SHELL_META.search(host): raise ValueError(f"Host contains forbidden characters: {host!r}") # Accept valid IP addresses directly. try: addr = ipaddress.ip_address(host) if not allow_internal and is_internal_ip(host): raise ValueError( f"Host {host} is an internal/private/loopback address — " "requests to internal addresses are blocked" ) return host except ValueError as exc: # Re-raise if it's our own SSRF block, not an ip_address parse error if "internal" in str(exc): raise pass if not _HOSTNAME_RE.match(host): raise ValueError(f"Invalid hostname: {host!r}") # If internal not allowed, resolve and check the IP if not allow_internal: _resolve_and_check(host) return host - src/sounding/validators.py:214-216 (helper)Validates that the port is an integer in the valid TCP/UDP range (1-65535).
def validate_port(port: int) -> bool: """Return True if *port* is in the valid TCP/UDP range (1–65535).""" return isinstance(port, int) and 1 <= port <= 65535 - src/sounding/server.py:33-33 (registration)The FastMCP instance used for tool registration via the @mcp.tool() decorator.
mcp = FastMCP("sounding")