IfPort docs
Check which TCP ports are visible from the network path making the request. IfPort never accepts an arbitrary target.
Quick start
Run the check from the agent, CI runner, server, container, or workstation whose path you want to understand.
curl -L 'ifport.io'
curl -L 'ifport.io/json'
The first command returns a compact terminal result. /json is the stable machine contract. If the observed source is private, proxied, or unexpected, open /network-path before drawing host-level conclusions.
ifport.io automatically redirects requests to the secure protocol; -L tells curl to follow that redirect.
Shell convention: these examples single-quote every URL.
Reference
Choose an output
GET /— compact terminal result or no-scan browser landing.GET /json— canonical machine response.GET /check— Markdown result;GET /plain— open port numbers only.GET /report— detailed human explanation;/report?format=json— structured explanation for agents.GET /network-path— no-scan source-attribution diagnostic.GET /statusandGET /trust— service and trust metadata.GET /openapi.json— compact API reference.
No-parameter scans use profile=default, speed=balanced, and ports 7,9,13,21,22,23,25,26,37,53,79,80,81,88,106,110,111,113,119,135,139,143,144,179,199,389,427,443,444,445,465,513,514,515,543,544,548,554,587,631,646,873,990,993,995,1025,1026,1027,1028,1029,1110,1433,1720,1723,1755,1900,2000,2001,2049,2121,2717,3000,3128,3306,3389,3986,4899,5000,5009,5051,5060,5101,5190,5357,5432,5631,5666,5800,5900,6000,6001,6646,7070,8000,8008,8009,8080,8081,8443,8888,9100,9999,10000,32768,49152,49153,49154,49155,49156,49157. Use profile=top1000 only for an explicit broad check.
Stable JSON fields
These fields are stable in 0.x. Ignore additional fields you do not recognize.
- Identity:
schema_version,service,generated_at,meta.build_id,meta.release_sha,meta.request_id. - Source:
observed_source.ip,observed_source.address_family,observed_source.scope,observed_source.attribution_confidence,observed_source.attribution_source. - Scan:
scan.strategy,scan.method,scan.method_counts,scan.vantage,scan.type,scan.profile,scan.speed,scan.ports_checked_count,scan.duration_ms,scan.partial,scan.partial_reason,scan.completed_ports_count,scan.skipped_ports_count. - Result:
results.open_ports_countandresults.openappear only when at least one open port is found. Detailed attempted and non-open outcomes are available only through the dedicated/report?format=jsoncompatibility route; new clients should addview=fullexplicitly. - Policy:
policy.verdict = pass|warn|fail|not_evaluated;policy.unexpected_open_portsappears only when non-empty. - Context:
limitations,links.network_path,links.report.
A bounded policy pass is not a security assessment.
Example JSON
GET /json returns a request-source result like this. Run the command from the exact network path you want to validate.
{
"generated_at": "2000-01-01T00:00:00Z",
"limitations": [
"This result describes the public request-source path.",
"If the request passed through NAT, VPN, proxy, CI/CD, cloud runtime, or an LLM sandbox, the result may not describe your local machine.",
"Unchecked ports are not assessed by the selected profile or explicit port list.",
"Policy verdicts apply only to the selected bounded policy and selected scan vantage; they are not a security assessment."
],
"links": {
"network_path": "https://ifport.io/network-path",
"report": "https://ifport.io/report"
},
"meta": {
"build_id": "example-build-not-live",
"release_sha": "image-example-not-live-0123456789abcdef0123456789abcdef",
"request_id": "req_0123456789abcdef0123456789abcdef"
},
"observed_source": {
"address_family": "ipv4",
"attribution_confidence": "high",
"attribution_source": "trusted_forwarded_header",
"ip": "203.0.113.42",
"scope": "public"
},
"policy": {
"name": "strict",
"verdict": "pass"
},
"scan": {
"completed_ports_count": 100,
"duration_ms": 326,
"method": "tcp_syn",
"method_counts": {
"tcp_syn": 100
},
"partial": false,
"partial_reason": null,
"ports_checked_count": 100,
"profile": "default",
"skipped_ports_count": 0,
"speed": "balanced",
"strategy": "syn_with_connect_fallback",
"type": "tcp_syn_or_connect",
"vantage": {
"count": 1,
"id": "primary",
"region": "eu"
}
},
"schema_version": "1.1",
"service": "ifport.io"
}
Errors, limits, and caching
JSON errors use meta plus error.code, error.message, and a server-generated X-Request-Id matching the body. Stable codes: invalid_request, invalid_ports, invalid_profile, invalid_format, invalid_view, invalid_result_token, invalid_delete_token, forbidden, method_not_allowed, not_found, policy_gate_failed, endpoint_gone, persisted_result_not_found, rate_limited, and service_unavailable. MCP errors use JSON-RPC and put correlation metadata in error.data.
409 gate failures use policy_gate_failed. Operator safe-mode and dependency outages use service_unavailable. 429 responses include Retry-After and RateLimit-* headers.
Shared limits per observed source are scan=30/min, custom=10/min, deep=3/min, and top1000=3/min. Core scan cache keys include the observed source IP, profile or custom ports, and speed; choosing compact JSON, MCP, or browser result presentation does not create a separate scan or rate-limit bucket.
Scan responses are noindex, noarchive. No-scan metadata endpoints accept HEAD; scan routes remain GET-only.
Advanced workflows
Formats and scoped checks
curl -fsSL 'ifport.io/?format=json'
curl -fsSL 'ifport.io/?format=markdown'
curl -fsSL 'ifport.io/?format=plain'
curl -fsSL 'ifport.io/report?format=json'
curl -fsSL 'ifport.io/check?ports=22,80,443,5432'
MCP clients
Use ifport.io/mcp as the Streamable HTTP endpoint. GET /mcp returns 405; MCP clients use POST.
Hosted MCP checks the MCP client or platform egress path. To inspect a local agent, CI runner, VPS, container, or workstation, call /json from that environment.
Send Accept: application/json, text/event-stream and MCP-Protocol-Version: 2025-11-25. Browser-based clients must send a trusted Origin; send MCP-Session-Id only if a future initialize response returns one.
Lifecycle: call initialize first, send notifications/initialized, then use tools/list and tools/call.
The tool is check_request_source_ports. It accepts only profile, ports, and speed; tools/list publishes its inputSchema and outputSchema.
The descriptor sets openWorldHint=true because the tool contacts ifport.io over the network. Target-like transport query parameters are rejected before JSON-RPC dispatch.
Successful MCP lifecycle and tool responses use Cache-Control: private, no-store; transport and JSON-RPC validation errors use Cache-Control: no-store.
curl -fsSL -X POST 'ifport.io/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"ifport-client","version":"1.0"}}}'
curl -fsSL -X POST 'ifport.io/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
--data '{"jsonrpc":"2.0","method":"notifications/initialized"}'
npx -y "@modelcontextprotocol/inspector@0.22.0" \
--cli 'https://ifport.io/mcp' \
--transport http \
--method tools/list
npx -y "@modelcontextprotocol/inspector@0.22.0" \
--cli 'https://ifport.io/mcp' \
--transport http \
--method tools/call \
--tool-name check_request_source_ports \
--tool-arg profile=default \
--tool-arg speed=balanced
Secondary and compatibility workflows
Default scans are ephemeral. Gate, evidence, verification, saved-result, trust, support, and donation routes remain available, but they are not active onboarding. Their full reference lives in /openapi-compat.json.
/action-plan, persisted evidence, and SVG cards are compatibility-only.
Source attribution uses trusted edge headers only after edge sanitization; otherwise it falls back to the transport source. Use /network-path as the diagnostic source of truth.
Compact result migration: response schema 1.1 replaces selected/completed/skipped port arrays with counts in normal JSON and MCP responses. Clients that intentionally consume per-port non-open outcomes must use the dedicated /report?format=json compatibility route; new clients should add view=full explicitly. There is no legacy view on the default contract.
Saved-result migration
Saved-result JSON clients must branch on schema_version. Version 2.0 removes the legacy top-level open_ports and closed_or_filtered_count fields and adds scan.speed plus distinct results.open, results.closed, results.filtered_or_timeout, results.errors, results.unclassified_legacy, and results.detail. Older stored rows use legacy_unknown or legacy_incomplete when the original detail cannot be reconstructed honestly; no query parameter converts version 2 back to the legacy shape. Use X-IfPort-Build to correlate the cutover or a rollback.
Docs · OpenAPI · Compat OpenAPI · MCP · LLMs · Status · Trust · Support
build_id: 2026.08.05.p354.j26457 · release_sha: 166114f9bec4