gqls
Fuzzy and semantic search over a GraphQL schema — from the terminal, for very large graphs.
Point gqls at a schema and find the type, field, argument, or directive you're after — by approximate name, by meaning, or jump straight to its resolver in code. It reads an SDL file, a local introspection dump, or a live endpoint, so you skip the part where you grep an SDL file, guess the exact spelling, and scroll. Built for schemas too big to scroll: GitHub's ~68k-line API answers in ~0.15s.
Why
Nothing else combines fuzzy/semantic search with big-schema speed in 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 emit JSON/NDJSON everywhere.
Install
# Homebrew (fuzzy + introspection + resolver jump + semantic search)
# Cargo (crate is `gqls-cli`; it installs the `gqls` binary)
# Cargo, with semantic search (downloads ONNX Runtime at build time)
The resolver jump (-R) shells out to rq; install it too if you want that.
Usage
Input sources
- SDL file —
gqls user schema.graphql - Introspection JSON dump —
gqls user schema.json - Live endpoint —
gqls user https://api.example.com/graphql(POSTs the introspection query) - Auto-discovery — omit the source and
gqlsfinds a schema in the current tree (preferring.graphqls, thenschema.*, then an introspection.json, then any SDL-looking.graphql).
Fuzzy search (default)
Handles abbreviations (usr → User), typos and transpositions (usre → User), and qualified Type.field queries. Results rank by match quality, with root Query/Mutation fields floated up.
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. The Homebrew build ships it (against the system onnxruntime); the plain cargo install needs --features semantic.
Per-record vectors are cached (keyed by schema content + model): 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, --clear-cache wipes the cache.
Resolver jump (-R, graphql-ruby)
Find a field, then jump to the resolver or method that implements it, via rq:
)
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 clean:
|
Shell completions: gqls --completions zsh (or bash/fish/…).
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 and 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.