A local, terminal-first client for the Glean Client REST API. Inspired by Claude Code. Built in Python with zero runtime dependencies.
- What you get
- Getting started — install, alias, first run
- Coming soon
- Commands at a glance
- Mock mode
- Natural-language planner
- Tokens and auth
- Config keys
- MCP server
- Project layout
- Running tests
- Documentation — the full reference set
- Changelog — release history
- License
- Every major Glean Client API surface as a slash command — chat, search, agents, tools, docs, people, shortcuts (Go Links), answers, summarize, verification, messages, activity, announcements, collections, pins, and insights
- Near-complete Indexing API coverage across read/debug, single-record write, bulk, and process-all tiers — including a debug toolkit that answers "is this doc uploaded?" and "why can't user X see doc Y?" without leaving the REPL. See docs/INDEXING.md
- Custom Metadata API for enriching already-indexed documents without re-uploading them. See docs/METADATA.md
- Indexing from local files —
/index.document --path file.mdand/index.bulk-documents --path ./docs/walk a file or folder and synthesize the request body for you, with--dry-runto inspect it first - Natural-language planner — type
?login into acme-be.glean.com and search for "Q2 plan"and Glean Assistant translates it into slash commands, validated locally and gated behind a single confirm for anything destructive - Offline by default — a real mock corpus of interlinked documents across five faux datasources, so every command is explorable without credentials. See docs/MOCK_CORPUS.md
- Browser SSO or API token —
/auth loginruns OAuth 2.1 + PKCE against your instance, or paste a Glean-issued token. Secure refs keep real secrets in environment variables, never on disk - MCP server (
glean_mcp.py) for Claude Code, Claude Desktop, and Cursor - Terminal niceties:
/help <command>for every command, tab completion that cycles matches, a powerline-style status bar, and/scaffoldto generate stdlib-only starter projects
cd glean-code-cli
python3 -m glean_codePython 3.9 or newer. No pip install required. Only the standard library is used.
After opening a new terminal just run glean.
alias glean="PYTHONPATH=<YOUR_PATH>/glean-code-cli python3 -m glean_code"Browser SSO (no API token to paste) — opens your browser for Glean → your company IdP, then stores OAuth tokens in ~/.gleancode/auth.json:
/auth login --instance acme-be.glean.com
/status
/search "quarterly planning"
/chat "summarise the Q2 plan"
Details: docs/SSO_OAUTH.md.
API token — paste a Glean-issued Client API token (same live API, different auth path):
/login --instance acme-be.glean.com --token <bearer_token>
/status
/search "quarterly planning"
/chat "summarise the Q2 plan"
Without Client API credentials (no /auth session and no /login token) the CLI runs in mock mode. After /auth login or /login, it switches to live calls against https://<instance>/rest/api/v1.
A native VS Code extension that brings the full Glean Code REPL — slash commands, status bar, mock/live switching, secure-token storage — into the editor sidebar. Run searches, kick off agents, and pin docs without leaving your code window.
| Area | Commands |
|---|---|
| Shell | /help /status /doctor /auth /login /logout /open /ask /config /mode /history /clear /exit |
| Chat and search | /chat /search /autocomplete /recommendations /feedback /datasources.list |
| Indexing — read & debug | /datasources.status /datasources.config /documents.status /documents.count /users.count /documents.access /debug.document /debug.documents /debug.user /indexing.rotate-token |
| Indexing — single write | /index.document /index.permissions /index.user /index.group /index.membership and their /index.delete-* partners |
| Indexing — bulk & process-all | /index.documents /index.bulk-documents /index.bulk-users /index.bulk-groups /index.bulk-memberships /shortcuts.bulk-index /shortcuts.upload /index.process-all-documents /index.process-all-memberships |
| Indexing — people (org chart) | /people.bulk-employees /people.bulk-teams /people.index-employee-list /people.process-all-employees-teams |
| Custom metadata | /metadata.set-schema /metadata.get-schema /metadata.delete-schema /metadata.attach /metadata.detach |
| Insights & activity | /insights /activity.report |
| Agents and tools | /agents.list /agents.run /tools.list /tools.call |
| Docs and people | /docs.get /docs.permissions /entities.list /people.get |
| Announcements, collections, pins | /announcements.list /announcements.create /announcements.delete /collections.list /collections.create /collections.delete /pins.list /pins.create /pins.delete |
| Shortcuts (Go Links) | /shortcuts.list /shortcuts.get /shortcuts.create /shortcuts.update /shortcuts.delete |
| Answers | /answers.list /answers.get /answers.create /answers.update /answers.delete |
| Verification | /verification.list /verification.verify /verification.remind |
| Summarize & messages | /summarize /messages.get |
| Scaffold | /scaffold chat /scaffold search /scaffold agent |
Type /help <command> for parameters, examples, and the underlying REST endpoint. Bare text with no leading slash is a shortcut for /chat.
Full per-command reference — usage, parameters, examples, endpoints — is in docs/COMMANDS.md.
Every command works offline. With no credentials configured, Glean Code serves ranked results from a built-in corpus of seventy interlinked documents belonging to one fictional company, spread evenly across five faux datasources (gdrive, confluence, jira, github, slack — fourteen each).
Because every mock endpoint reads from the same corpus, offline mode behaves like one coherent index rather than a pile of placeholders — a URL from /search resolves in /docs.get, /summarize, and /chat citations:
/search "quarterly planning" # ranked against the corpus
/search "checkout incident" --datasource jira # the datasource filter really filters
/summarize --url <url from result 2> # summarises that same document
/docs.get --url <url from result 2> # same title, author and datasource
/chat "how do we run quarterly planning?" # cites documents that exist
Point mock_corpus_path at a JSON file to swap in your own corpus for a tailored demo. Full reference, document inventory, ranking notes, and the custom-corpus file format: docs/MOCK_CORPUS.md.
Don't remember the exact slash-command incantation? Describe what you want and Glean Assistant translates it into commands for you.
?login into acme-be.glean.com with my stored token, then search for "Q2 plan"
/ask "show me datasource health and start a chat"
Both forms invoke the same handler — ? is the REPL shorthand, /ask "..." is the explicit form (handy for scripts and pipes). Glean Code builds a catalogue of every registered command, sends it with your request, validates each returned step against the live command set, and shows a numbered plan. Pure reads run automatically; writes, deletes, and auth changes trigger a single Run all? [y/N] gate. Tokens never leave the local process — the planner sees only the placeholder <stored>.
It works offline too: in mock mode the CLI pattern-matches locally and emits a canned plan instead of calling Glean.
Full design — architecture, prompt template, destructive set, troubleshooting: docs/NATURAL_LANGUAGE.md.
Three ways to authenticate, in order of preference:
| Method | How | Notes |
|---|---|---|
| Browser SSO | /auth login --instance <host> |
OAuth 2.1 + PKCE, same SSO path as the web app. Tokens in ~/.gleancode/auth.json. See docs/SSO_OAUTH.md |
| Secure ref | /login --token token.secure.client |
Config stores the reference name; the real secret resolves from $GLEAN_CLIENT_TOKEN at request time. See docs/SECURE_TOKENS.md |
| Literal token | /login --token <bearer_token> |
Written to ~/.gleancode/config.json with 0o600 perms, masked to ***1234 everywhere it displays |
The Client API and the Indexing API take separate tokens — a Client token cannot reach /api/index/v1. Set the indexing one with /config set indexing_token <token-or-secure-ref>. Indexing still uses a Glean-issued token even when the Client API is on SSO.
Tokens are stripped from the in-memory history buffer and masked on every display surface. See docs/SECURE_TOKENS.md for the full masking matrix.
| Key | Description | Values |
|---|---|---|
instance |
Glean backend host | e.g. acme-be.glean.com |
api_token |
Client API bearer token | Glean-issued token, or a secure ref like token.secure.client |
indexing_token |
Indexing API token | Glean-issued token, or token.secure.indexing |
act_as |
Impersonate a user via X-Glean-ActAs |
Email address |
base_url |
Override the computed base URL | Full URL |
mode |
API mode | auto (default), live, mock |
theme |
Terminal colour theme | glean (default), mono, neon |
default_page_size |
Default result count for search and entities | Integer, default 10 |
mock_corpus_path |
JSON file backing mock mode | Path; unset uses the built-in corpus |
Config lives at ~/.gleancode/config.json. Change any key with /config set <key> <value>. Use /mode live|mock|auto to force a mode without editing config.
glean_mcp.py exposes Glean as an MCP server so Claude Code, Claude Desktop, and Cursor can call Glean search, chat, and agents as native tools. It reads the same ~/.gleancode/config.json but forces live mode, so MCP tools hit the real API by default — mock mode is opt-in via GLEAN_MOCK and every mock response carries a visible fabricated-data banner.
Requires Python 3.10+ and the mcp package. The REPL itself remains Python 3.9+ and stdlib-only.
Setup for all three clients, the tool table, and the mock-mode rationale: docs/MCP.md.
glean-code-cli/
glean_mcp.py MCP server entry point
glean_code/
__main__.py python -m glean_code
cli.py REPL loop and banner
commands.py slash command parser and handlers
client.py Glean REST wrapper + mock responses
config.py config file load and save
help_docs.py per-command documentation
mock_corpus.py the fake corpus every mock endpoint reads from
_indexing_walk.py --path file walking for indexing commands
completion.py readline tab completion
scaffold.py project scaffold templates
ui.py ASCII art, colours, boxes
auth_commands.py /auth command handlers
auth/ OAuth 2.1 + PKCE: oauth, pkce, callback_server,
token_store, manager
tests/ 15 test modules, stdlib unittest only
docs/ full reference set — see below
The test suite uses only the standard library (no mocking frameworks, no network calls).
python3 -m pytest tests/Or without pytest:
python3 -m unittest discover tests/699 tests covering the client and every mock response, commands and dispatch, config, UI, auth, completion, help docs, the mock corpus, indexing-walk, scaffold, and the MCP server. Development notes: docs/TESTING.md.
| Doc | What's in it |
|---|---|
| docs/COMMANDS.md | Full per-command reference — usage, parameters, examples, endpoints |
| docs/INDEXING.md | Indexing API: read/debug, writes, bulk, process-all, --path mode |
| docs/METADATA.md | Custom Metadata API: schemas and document attachment |
| docs/INSIGHTS.md | /insights flags, output, and CSV export |
| docs/MOCK_CORPUS.md | The offline corpus — inventory, ranking, bring-your-own format |
| docs/NATURAL_LANGUAGE.md | Planner design, prompt template, destructive set |
| docs/SSO_OAUTH.md | Browser SSO via OAuth 2.1 + PKCE |
| docs/SECURE_TOKENS.md | Secure refs, masking matrix, mock-mode fallback |
| docs/MCP.md | MCP server setup for Claude Code, Claude Desktop, Cursor |
| docs/REST_PATHS.md | Every REST path this client targets, and how to retarget them |
| docs/TESTING.md | Test-suite development notes |
| CHANGELOG.md | Release history |
MIT © 2026 barkz

