SIGN IN SIGN UP

Serve the discovery scopes `hf_fs` advertises

The captured tool document names `hf://models|datasets|spaces[/OWNER]` as
search scopes and prints `ls hf://models/openai --sort downloads --limit 20`
as an example. The fake refused every URI shorter than three segments, in a
sentence telling the caller it had mistyped -- "EINVAL: expected
hf://datasets/<namespace>/<name>" -- and refused `search` outright.

Not hypothetical. A benchmark run opened with

  {"operations":[{"cmd":"ls","args":["hf://datasets/integ-org","--limit","100"]},
                 {"cmd":"search","args":["hf://datasets","Annoy","--limit","50"]}]}

was refused both, retried the listing twice, and answered "the GitHub issue
and Hugging Face dataset repositories were unavailable through the connected
services". Every URI it sent is in the grammar the server itself handed it.
The draw was discarded and the cause was unexplained until now.

`locate` now returns the scope rather than an error, and `discoverOne` answers
the two new ones off the listing route the REST arm already serves -- one
world, one implementation, which is the whole point of the arm.

Captured, not reasoned about, from https://huggingface.co/mcp on 2026-09-01:

* a repository row's Details cell, and its structured twin: `updated_at`
  rather than `lastModified`, `gated: false` present on a model that is not
  gated, `gated=manual` BESIDE `public` rather than instead of it, and a
  Space carrying neither `downloads` nor `gated` but carrying `sdk` where a
  model carries `task`;
* two different truncation notices -- `ls` says `entry_limit` with a
  sentence naming the 10,000 ceiling, `search` says `limit` with no message
  at all and a ceiling of 1,000;
* `stat hf://models/<owner>` reporting `exists: yes, type: namespace` for an
  owner that does not exist, because the server describes the URI's shape
  rather than the Hub's contents;
* `search` on a repository URI, refused by naming every scope that would
  have worked;
* `ls --type file` on a namespace answering an empty table rather than an
  error.

Two things are still refused, both for what the fake does not hold rather
than by calling the URI wrong: `ls hf://<kind>`, whose only entry upstream is
a `trending` directory with no feed behind it, and the five `--sort` keys the
listing route has no column for. Repository-scope flags (`--recursive`,
`--glob`, `--name`, `--path`) are untouched and still refused by name.

The structured listing result now puts `entries` before the truncation keys,
which is the order the live result serializes in and therefore the order the
model reads.

304 checks, up from 271.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Z
Zecheng Zhang committed
370d20bef91027f8ecd0a4351b21a07fbc65d1f7
Parent: 9599508