gtrace
August 19, 2026 · View on GitHub
Advanced network path analysis tool combining local traceroute with GlobalPing's distributed probe network.

Why gtrace?
| Feature | gtrace | mtr | traceroute |
|---|---|---|---|
| MPLS label detection | Yes | No | No |
| ECMP/load balancing detection | Yes | No | No |
| Active ECMP probing (Paris-style) | Yes | No | No |
| NAT detection | Yes | No | No |
| Path MTU discovery | Yes | No | No |
| GlobalPing integration | Yes | No | No |
| ASN + geolocation enrichment | Yes | Partial | No |
| IPv4/IPv6 dual-stack | Yes | Yes | Yes |
| MTR-style continuous mode | Yes | Yes | No |
| Latency jitter (StdDev) | Yes | Yes | No |
| JSON/CSV export | Yes | Yes | No |
| MCP server (AI integration) | Yes | No | No |
| Built-in self-update | Yes | No | No |
Features
- Multi-Protocol Traceroute: ICMP, UDP, and TCP probing
- IPv4/IPv6 Support: Dual-stack with
-4and-6flags - MPLS Detection: Extract and display MPLS label stacks from ICMP extensions
- ECMP Detection: Passive detection of load-balanced paths with multiple IPs per hop
- Active ECMP Probing: Paris traceroute-style flow variation to actively discover ECMP paths
- NAT Detection: Identify NAT devices along the path via response TTL analysis
- Path MTU Discovery: Active per-hop MTU discovery (tracepath-style) with PMTUD black-hole detection
- Rich Enrichment: ASN lookup, reverse DNS, geolocation, IX detection
- MTR Mode: Continuous monitoring with real-time statistics including latency jitter (StdDev)
- GlobalPing Integration: Run traces from 500+ global probe locations
- Export Formats: JSON, CSV, and text output
- MCP Server: Expose all tools to AI assistants (Claude Code, Cursor, etc.) via Model Context Protocol
Installation
Precompiled Binaries
Download the latest release for your platform from the Releases page.
Available for Linux and macOS (amd64 and arm64).
# Linux amd64
VERSION=$(curl -sI https://github.com/hervehildenbrand/gtrace/releases/latest | grep -i location | sed 's/.*tag\/v//' | tr -d '\r')
curl -LO "https://github.com/hervehildenbrand/gtrace/releases/download/v${VERSION}/gtrace_${VERSION}_linux_amd64.tar.gz"
tar xzf "gtrace_${VERSION}_linux_amd64.tar.gz"
sudo mv gtrace /usr/local/bin/
# macOS Apple Silicon
VERSION=$(curl -sI https://github.com/hervehildenbrand/gtrace/releases/latest | grep -i location | sed 's/.*tag\/v//' | tr -d '\r')
curl -LO "https://github.com/hervehildenbrand/gtrace/releases/download/v${VERSION}/gtrace_${VERSION}_darwin_arm64.tar.gz"
tar xzf "gtrace_${VERSION}_darwin_arm64.tar.gz"
sudo mv gtrace /usr/local/bin/
From Source
go install github.com/hervehildenbrand/gtrace/cmd/gtrace@latest
Build Locally
git clone https://github.com/hervehildenbrand/gtrace.git
cd gtrace
go build -o gtrace ./cmd/gtrace
Quick Start
# Basic ICMP traceroute
sudo gtrace 8.8.8.8 --simple
# UDP traceroute with ECMP detection
sudo gtrace cloudflare.com --simple --protocol udp --packets 6
# Active ECMP probing (Paris traceroute-style)
sudo gtrace cloudflare.com --simple --protocol udp --ecmp-flows 8
# TCP traceroute to specific port
sudo gtrace example.com --simple --protocol tcp --port 443
# NAT detection
sudo gtrace 8.8.8.8 --simple --detect-nat
# Path MTU discovery (per-hop, with black-hole detection)
sudo gtrace mtu 8.8.8.8
# MTR-style continuous monitoring
sudo gtrace 8.8.8.8
# Compare local and remote traces
sudo gtrace 8.8.8.8 --compare --from "New York,London"
# Visual path graph (git-log style DAG): paths from multiple probes
# converging toward the destination, convergence points highlighted
gtrace 8.8.8.8 --graph --from "Paris;Frankfurt;Tokyo"
# Path graph of the local trace (shows ECMP forks)
sudo gtrace 8.8.8.8 --graph
# IPv6 traceroute
sudo gtrace -6 google.com --simple
# Compare IPv6 local vs remote
sudo gtrace -6 google.com --compare --from Paris
Usage
Basic Options
| Flag | Description | Default |
|---|---|---|
-4, --ipv4 | Force IPv4 only | false |
-6, --ipv6 | Force IPv6 only | false |
--protocol | Protocol: icmp, udp, tcp | icmp |
--port | Target port (TCP/UDP) | 33434 |
--max-hops | Maximum TTL | 30 |
--packets | Probes per hop | 3 |
--timeout | Per-hop timeout | 500ms |
--simple | Simple output (no TUI) | false |
--graph | Render path graph after trace (no TUI) | false |
Detection & Discovery
| Flag | Description | Default |
|---|---|---|
--detect-nat | Enable NAT detection via TTL analysis | false |
--ecmp-flows | ECMP flow variations per hop (0=disabled) | 0 |
--mtu | Active per-hop Path MTU Discovery with black-hole detection (icmp/udp) | false |
--probe-size | Probe packet size in bytes | 64 |
--discover-mtu remains as a deprecated alias for --mtu.
MTR Mode
| Flag | Description | Default |
|---|---|---|
--interval | Time between cycles | 1s |
--cycles | Number of cycles (0=infinite) | 0 |
Keyboard shortcuts in MTR mode:
p- Pause/Resumer- Reset statisticsn- Toggle DNS/IP displayq- Quit
GlobalPing Integration
| Flag | Description |
|---|---|
--from | Probe locations, comma-separated (max 5) |
--compare | Compare local trace with remote probes |
--api-key | GlobalPing API key for higher rate limits |
Export
| Flag | Description |
|---|---|
-o, --output | Export to file (format auto-detected from extension) |
--format | Explicit format: json, csv, text (or txt) |
Enrichment
| Flag | Description |
|---|---|
--offline | Use only local GeoIP databases |
--db-status | Show GeoIP database status |
--download-db | Instructions to download GeoIP databases |
Self-Update
gtrace checks for new versions on startup and displays a notification after the trace completes. To upgrade in place:
gtrace upgrade # Interactive prompt
gtrace upgrade --force # Non-interactive
| Environment Variable | Description |
|---|---|
GTRACE_NO_UPDATE_CHECK=1 | Disable the automatic update check on startup |
Examples
Detect MPLS Labels
sudo gtrace www.internet2.edu --simple
Output shows MPLS labels on backbone hops:
8 129.250.2.106 [AS2914] 202ms [MPLS: L=309833 E=0 S=1 TTL=1]
9 129.250.6.6 [AS2914] 79ms [MPLS: L=36001 E=0 S=1 TTL=1]
Detect Load Balancing (ECMP)
# Passive detection: send multiple probes and observe path divergence
sudo gtrace cloudflare.com --simple --protocol udp --packets 8
# Active probing: Paris traceroute-style flow variation
sudo gtrace google.com --simple --protocol udp --ecmp-flows 8
Multiple IPs at the same hop indicate ECMP:
6 72.14.202.232 72.14.205.190 193.251.255.104 72.14.204.184 [AS15169] 3.44ms
Detect NAT Devices
sudo gtrace 8.8.8.8 --simple --detect-nat
NAT devices are identified by TTL anomalies in ICMP responses:
3 10.0.0.1 [AS3215] 5.42ms 4.89ms 5.01ms [NAT]
7 72.14.236.73 [AS15169] 8.21ms 7.98ms 8.44ms [NAT]
Path MTU Discovery
sudo gtrace mtu 8.8.8.8 # dedicated subcommand
sudo gtrace 8.8.8.8 --simple --mtu # or as a flag on a normal trace
Actively discovers each hop's MTU (tracepath-style): probes carry the
Don't Fragment bit starting at the egress interface MTU, and ICMP
Fragmentation Needed / Packet Too Big replies (IPv4 and IPv6) shrink the
probe until the path is measured. Works with --protocol icmp (default)
and udp; TCP SYN probes have a fixed size and are not supported.
1 192.168.1.1 0.87ms [MTU:1500]
2 80.10.255.25 [AS3215] 1.57ms [MTU:1500]
3 10.20.0.1 [AS3215] 5.42ms [MTU:1400]
Trace complete: reached 8.8.8.8 in 9 hops
Path MTU: 1400
When a hop silently drops oversized packets without sending ICMP feedback (a PMTUD black hole - the classic cause of hanging TLS handshakes and stuck downloads), gtrace binary-searches the boundary and flags it:
4 203.0.113.9 12.10ms [MTU:1400 blackhole]
The TUI shows the same as a compact [MTU:1400!] marker.
IPv6 Traceroute
# Force IPv6
sudo gtrace -6 google.com --simple
# Compare IPv6 paths from different locations
sudo gtrace -6 cloudflare.com --compare --from "Frankfurt,Singapore"
Export to JSON
sudo gtrace 8.8.8.8 --simple -o trace.json
JSON includes full hop data with ASN, geolocation, timing, and detection results:
{
"target": "8.8.8.8",
"pathMtu": 1500,
"hops": [
{
"ttl": 1,
"ip": "192.168.1.1",
"avgRtt": 0.5,
"lossPercent": 0,
"nat": true,
"mtu": 1500,
"mtuBlackhole": false
}
]
}
pathMtu and mtuBlackhole appear when MTU discovery ran (--mtu).
Compare Local vs Remote
# Compare against a single remote location
sudo gtrace 8.8.8.8 --compare --from Paris
# Compare against multiple remote locations (up to 5)
sudo gtrace 8.8.8.8 --compare --from "Paris,Tokyo"
Each remote location produces its own side-by-side comparison against the local trace, separated by ===. Column headers show the actual probe location (e.g. "Paris, FR, OVH SAS").
MCP Server (AI Integration)
gtrace includes a built-in MCP server that exposes its tools to AI assistants like Claude Code, Cursor, and other MCP-aware clients.
Available Tools
| Tool | Description | Needs Root |
|---|---|---|
traceroute | Full traceroute with ASN, geo, MPLS enrichment | Yes |
mtr | MTR report with packet loss and latency stats | Yes |
globalping | Remote traceroute from worldwide probe locations | No |
list_probes | Discover GlobalPing probe locations (filter by country, city, ASN, network) | No |
ping | Distributed ICMP/TCP ping via GlobalPing | No |
dns | Distributed DNS lookup via GlobalPing (all record types, trace mode) | No |
asn_lookup | ASN info for an IP (org, prefix, country) | No |
geo_lookup | Geolocation for an IP (city, coords, timezone) | No |
reverse_dns | Reverse DNS hostname lookup | No |
Output Formats
Every tool accepts format: "text" (default, human-readable) or format: "json", which returns machine-readable data in the MCP result's structuredContent field. traceroute and globalping also accept view: "graph" to render the visual path graph (forks, merges, per-source strands) instead of the classic table; view is ignored when format is json.
The traceroute tool's discover_mtu parameter runs active per-hop Path MTU Discovery (icmp/udp only): results include each hop's MTU, PMTUD black-hole flags, and the end-to-end pathMtu. GlobalPing probes cannot vary packet size, so the globalping tool does not support MTU discovery.
Setup with Claude Code
# Add gtrace as an MCP server (requires sudo for traceroute/mtr)
claude mcp add gtrace -- sudo gtrace mcp
# Or without sudo (only lookup + globalping tools will work)
claude mcp add gtrace -- gtrace mcp
# With a GlobalPing API key for higher rate limits
claude mcp add gtrace -- sudo gtrace mcp --api-key YOUR_KEY
Restart Claude Code after adding. The tools appear as mcp__gtrace__traceroute, mcp__gtrace__asn_lookup, etc.
Setup with Other MCP Clients
Add to your MCP client configuration:
{
"gtrace": {
"command": "sudo",
"args": ["gtrace", "mcp"]
}
}
Privilege Requirements
- macOS:
sudois required for traceroute/mtr (raw socket access) - Linux: Either
sudoor grant the binaryCAP_NET_RAW:sudo setcap cap_net_raw+ep $(which gtrace) gtrace mcp # no sudo needed - Lookup tools (
asn_lookup,geo_lookup,reverse_dns) and globalping never need elevated privileges
Architecture
gtrace/
├── cmd/gtrace/ # CLI entry point
├── internal/
│ ├── trace/ # Traceroute engines (ICMP, UDP, TCP)
│ ├── display/ # TUI and simple output renderers
│ ├── enrich/ # ASN, geo, rDNS enrichment
│ ├── export/ # JSON, CSV, text exporters
│ ├── globalping/ # GlobalPing API client
│ ├── mcp/ # MCP server for AI integration
│ ├── monitor/ # Route change detection
│ └── update/ # Auto-update and self-upgrade
└── pkg/hop/ # Hop data structures
Requirements
- Go 1.24+
- Root/sudo privileges for raw socket access
- Optional: MaxMind GeoIP databases for offline geolocation
License
MIT