gqls-cli 0.1.0

Fuzzy and semantic search over a GraphQL schema (SDL, introspection JSON, or a live endpoint), plus a field-to-resolver jump.
Documentation

gqls

Fuzzy and semantic search over a GraphQL schema — from the terminal, for very large graphs.

crates.io license

Point gqls at a schema — an SDL file, a local introspection dump, or a live endpoint — and find the type, field, argument, or directive you're after by approximate name, by meaning, or jump straight to its resolver in code. Built for schemas too big to scroll (GitHub's ~68k-line API answers in ~0.15s).

gqls user schema.graphql              # fuzzy: usr, usre, User.email all work
gqls repository https://api/graphql   # introspect a live endpoint
gqls 'cancel a subscription' -s       # semantic: rank by meaning
gqls Query.user -R --code ./app       # jump to the graphql-ruby resolver

Why

Existing tools don't combine fuzzy/semantic search with big-schema speed from a CLI: schema viewers list and filter but don't fuzzy-match, hosted explorers are GUIs, and the semantic-search tools are built for agents, not developers. gqls fills that gap and stays Unix-composable (-j/-J for JSON/NDJSON everywhere).

Install

# Homebrew (fuzzy + introspection + resolver jump)
brew install dpep/tools/gqls

# Cargo (crate is `gqls-cli`; it installs the `gqls` binary)
cargo install gqls-cli

# Cargo, with semantic search (downloads ONNX Runtime at build time)
cargo install gqls-cli --features semantic

The resolver jump (-R) shells out to rq; install it too if you want that.

Usage

Input sources

  • SDL filegqls user schema.graphql
  • Introspection JSON dumpgqls user schema.json
  • Live endpointgqls user https://api.example.com/graphql (POSTs the introspection query)
  • Auto-discovery — omit the source and gqls finds a schema in the current tree (preferring .graphqls, then schema.*, then an introspection .json, then any SDL-looking .graphql).

Fuzzy search (default)

Abbreviations (usrUser), transpositions/typos (usreUser), and qualified Type.field queries all work; results rank by match quality with root Query/Mutation fields floated up.

gqls createUser -k mutation      # restrict to a kind (plurals ok: mutations)
gqls User.email                  # qualified — boosts the field on User

Semantic search (-s, requires --features semantic)

Ranks by meaning using a local all-MiniLM-L6-v2 model (via ONNX Runtime), fetched once from the HuggingFace Hub then cached offline.

gqls 'delete a repository' -s https://api/graphql

Per-record vectors are cached (keyed by schema content + model), so the first run on a large schema embeds everything once (parallelized across cores) and later runs only embed the query — GitHub's schema: cold ~40s, warm ~0.3s. Editing the schema re-embeds automatically; --refresh forces it and --clear-cache wipes the cache.

Resolver jump (-R, graphql-ruby)

Find a field, then jump to the resolver/method that implements it, via rq:

$ gqls Query.user schema.graphql -R --code ./app
app/graphql/resolvers/user.rb:2  User  (via Resolvers::User)

gqls tries graphql-ruby naming conventions (resolver class, type method, mutation class) and ranks the candidates.

Output

Every mode supports -j/--json (pretty array) and -J/--ndjson (one record per line); status chatter goes to stderr, so JSON pipes cleanly:

gqls repository schema.json -J | jq -r '.path'

Using with Claude Code

Drop a small skill into ~/.claude/skills/gqls/ (see claude/gqls-skill.md in this repo) so Claude reaches for gqls when navigating a GraphQL schema instead of grepping SDL by hand.

How it works

Layered so the core is one idea — flatten every schema entity to a searchable record, and let search/output touch nothing but records:

src/
  model.rs        SchemaRecord + Kind (the only shared vocabulary)
  load/           SDL parse · introspection (URL/JSON) · schema discovery
  search/         the fuzzy scorer (a DP subsequence aligner + typo tier)
  semantic/       embedding search + on-disk vector cache (feature = "semantic")
  resolve.rs      field -> resolver jump (shells out to rq)
  cli.rs          clap + unified text/json/ndjson output

Two capabilities are borrowed from sibling tools rather than reinvented: the fuzzy ranking is ported from rq's aligner, and the local embedding pipeline is copied from ae.

License

MIT — see LICENSE.