Your Code Editor Is Phoning Home: huggingface_hub Silently Fingerprints 26 AI Coding Agents
A network-traffic audit found the huggingface_hub SDK scanning environment variables for 26 coding agents — from Claude Code and Cursor to Warp and Zed — and tagging every Hub request with an agent/<name> user-agent. Hugging Face publishes the aggregate numbers monthly; most developers never knew the telemetry existed.
Your Code Editor Is Phoning Home: huggingface_hub Silently Fingerprints 26 AI Coding Agents
On September 12, 2026, a network-traffic audit surfaced on r/LocalLLaMA landed like a small privacy earthquake in the machine-learning community: the huggingface_hub Python SDK — the substrate under transformers, datasets, gradio, faster-whisper and hundreds of downstream libraries — quietly scans your environment variables to determine which AI coding agent you are using, then stamps that identity onto every single request it sends to the Hugging Face Hub.
If you develop with Cursor, Claude Code, OpenAI Codex, GitHub Copilot, Zed, Warp, Replit, or any of roughly two dozen other agentic tools, and you have ever downloaded a model or dataset, the Hub very likely knows — and has been aggregating that knowledge into a public dataset since April 2026.
What the audit found
The mechanics, confirmed by inspecting the huggingface_hub source, are disarmingly simple. Every HTTP request the SDK makes first builds its headers via build_hf_headers(). Inside that call, a function named _http_user_agent() assembles the user-agent string — Python version, hf_hub version, optionally the installed PyTorch version — and then, unless telemetry is explicitly disabled, appends one more segment:
agent/<harness-id>
The <harness-id> comes from detect_agent(), a routine defined in utils/_detect_agent.py whose entire job is to fingerprint your process. It works in two layers. First, it checks the “standard” environment variables AI_AGENT and AGENT, which any tool can set to self-identify. Second — and this is the part that surprised people — it walks a registry of 26 known harnesses, each with its own fingerprinting signatures, and pattern-matches your process environment against them.
The 26-harness registry
The registry is not even hardcoded in the client. It is served live from the Hub at /api/agent-harnesses, cached locally for up to 24 hours so the list can grow without shipping a new release. As of this week it contains 26 entries:
Antigravity, Augment CLI, Cline, Claude Code (and its Cowork variant), Codex, Crush, Gemini CLI, GitHub Copilot, Goose, Hermes Agent, Hi, Kilo Code, Kiro, OpenClaw, Sandbase Harness, OpenCode, Pi, Replit, Trae, VTCode, Warp, Zed, Cursor CLI, Cursor, and Devin.
The detection signatures are env-var globs. Cursor is detected via CURSOR_TRACE_ID; Cursor’s CLI flavor via CURSOR_AGENT; Claude Code via CLAUDECODE or CLAUDE_CODE; Codex via CODEX_SANDBOX, CODEX_CI or CODEX_THREAD_ID; Warp via TERM_PROGRAM being set to WarpTerminal — a variable most terminal users had no idea identified them so precisely. Replit is detected through REPL_ID. Several, including Devin, match any non-empty value of their signature variable. If a standard variable is set to an unrecognized value, the SDK reports agent/unknown — and “unknown” is itself a tracked category.
The dataset that makes it concrete
What elevates this from “quirk” to “story” is that Hugging Face does not merely collect these signals — it publishes them. The huggingface/agent-usage dataset, updated by a scheduled job, reports each harness’s share of agent-attributed Hub traffic, month by month.
The August 2026 numbers are a snapshot of the coding-agent market few surveys can match:
| Agent | % of requests | % of distinct users |
|---|---|---|
| claude-code | 46.53 | 38.71 |
| codex | 17.52 | 23.34 |
| unknown | 14.13 | 16.15 |
| cursor-cli | 14.04 | 5.38 |
| hermes-agent | 3.88 | 5.83 |
| antigravity | 1.62 | 5.08 |
Claude Code alone accounts for nearly half of all agent-tagged Hub requests. A striking detail: Cursor CLI generates 14% of requests from just 5.4% of users — automation-heavy usage running much hotter per seat than interactive coding. And the “unknown” bucket, at 14% of traffic, is large enough to be a mid-tier agent on its own; these are tools that set AI_AGENT to a value outside the registry, or harnesses not yet registered.
July showed the same shape (Claude Code 44.2%, Codex 20.7%, unknown 23.2%), with Claude Code’s share still climbing month over month.
Why people are upset
Hugging Face’s documentation frames the mechanism as opt-in observability: registering your harness in the public registry (a pull request to agent-harnesses.ts in the @huggingface/tasks package) means traffic is “attributed to your tool by name,” earns it a friendly label and doc links, and gets it counted in the public dataset instead of the anonymous “unknown” aggregate. From the platform’s perspective this is developer relations, not surveillance — the data answers real questions about which tools the ML community actually uses.
The community’s objection is not that the data is secret — it is public — but that the collection was not. Every developer who pip-installed transformers and pulled a checkpoint through an agentic tool was enrolled in a telemetry program without a prompt, a checkbox, or, in most cases, awareness. The fingerprinting rides implicitly through the dependency tree: you interact with transformers or faster-whisper, they import huggingface_hub, and your editor identity ships to the Hub as a side effect of a model download. No consent dialog exists because the unit of consent — the developer’s shell environment — was never asked.
How to opt out
For those who want the telemetry gone, the switches are documented, if not prominent:
export HF_HUB_DISABLE_TELEMETRY=1 # disables agent fingerprinting and usage telemetry
export HF_HUB_OFFLINE=1 # fully offline mode; disables all Hub calls
HF_HUB_DISABLE_TELEMETRY=1 is the surgical option — the user-agent then omits the agent/ segment (and the torch/ version segment) entirely. Loading models from a local path rather than resolving them against the Hub achieves the same effect for that workflow. Note that telemetry is also automatically suppressed in offline mode, since no requests occur at all.
The bigger picture
This incident is less about Hugging Face specifically and more about where the industry’s default settings have drifted. Package managers, build tools, and now ML libraries have normalized background telemetry; what is new is the granularity — not “a Python developer downloaded a model” but “a Cursor user, on this machine, fetched this checkpoint, through this dependency chain, at this time.”
For companies running coding agents against proprietary stacks, the disclosure has a compliance edge: environment-derived telemetry flowing to a third-party platform may need to appear in data-processing inventories. For individual developers, it is a reminder that your shell environment is a broadcast surface — the variables set by your tools identify you more reliably than any cookie.
Hugging Face has been responsive to feedback in the past, and the public dataset argues the company sees this as transparency rather than extraction. But the r/LocalLLaMA thread’s top sentiment will likely shape the next iteration of the design: aggregate all you want, but tell people at install time, not at audit time.
Sources
- [1] https://www.reddit.com/r/LocalLLM/comments/1wehgvc/huggingface_hub_silently_fingerprints_which_ai/
- [2] https://huggingface.co/docs/huggingface_hub/en/package_reference/environment_variables
- [3] https://huggingface.co/docs/hub/en/agents-overview
- [4] https://huggingface.co/datasets/huggingface/agent-usage
- [5] https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/utils/_detect_agent.py