A local, terminal-first client for the Glean Client REST API. Inspired by Claude Code. Built in Python with zero runtime dependencies.
- Slash commands for every major Glean Client API surface: chat, search, agents, tools, docs, people, announcements, collections, pins, and insights
- Full in-terminal documentation for every command via
/help <command> - Tab completion that cycles through matches as you type — press Tab to step forward, Shift+Tab to step back
- Powerline-style status bar showing mode, connected instance, auth state, and active chat thread
- Datasource status enrichment via the Indexing API — uploaded/indexed counts, coverage %, and processing history
/scaffoldto generate a self-contained Python starter project for chat, search, or agent use cases- MCP server (
glean_mcp.py) for Claude Code, Claude Desktop, and Cursor - Config stored at
~/.gleancode/config.json— supports both Client and Indexing API tokens - Mock mode by default so you can try every command offline; switches to live the moment you add credentials
- Test suite in
tests/covering the client, config, and UI layers — run withpython3 -m pytest tests/
cd glean-code-cli
python3 -m glean_code
# or
./glean-codePython 3.9 or newer. No pip install required. Only the standard library is used.
After opening up a new terminal just run glean.
alias glean="PYTHONPATH=<YOUR_PATH>/glean-code-cli python3 -m glean_code"/login --instance acme-be.glean.com --token <bearer_token>
/status
/search "quarterly planning"
/chat "summarise the Q2 plan"
Without a token the CLI runs in mock mode and returns realistic fake data. Set a token with /login and it switches to live calls against https://<instance>-be.glean.com/rest/api/v1.
/chat/search/datasources.list/datasources.list --with-status/autocomplete/recommendations/feedback
/announcements.list/announcements.create/announcements.delete/collections.list/collections.create/pins.list/pins.create
Type /help <command> for parameters, examples and the underlying REST endpoint. Bare text with no leading slash is a shortcut for /chat.
Show help for a specific command, or list every available command grouped by category.
/help [command]
| Parameter | Description |
|---|---|
command |
Optional. Command name without the leading /. Omit to list all commands. |
/help
/help search
/help agents.run
Output — Without an argument: a grouped list of all commands with one-line summaries. With a command name: usage signature, parameter table, examples, and the underlying REST endpoint.
Endpoint — (local)
Show the current connection state, active mode, configured instance, and any impersonation in effect.
/status
/status
Output — A summary box showing: mode (live / mock / auto), instance host, token presence, act-as email if set, and the active chat thread id.
Endpoint — (local)
Run a full health check: validates config, tests DNS resolution, TCP connectivity, and performs a live auth probe against the search endpoint.
/doctor
/doctor
Output — A line per check (config, url shape, dns, tcp, auth probe) with a pass/fail status and detail message. Useful for diagnosing connectivity or token problems.
Endpoint — (local checks + POST /rest/api/v1/search probe)
Store a Glean instance host and API token. Writes to ~/.gleancode/config.json and immediately switches the session to live mode.
/login --instance <host> --token <token> [--act-as <email>]
| Parameter | Description |
|---|---|
--instance |
Full Glean backend host, e.g. acme-be.glean.com. Include the -be suffix — nothing is appended automatically. |
--token |
A Glean Client API token with the required scopes. |
--act-as |
Optional. Email address to impersonate via X-Glean-ActAs. |
/login --instance acme-be.glean.com --token glean_tok_xxx
/login --instance acme-be.glean.com --token glean_tok_xxx --act-as jane@acme.com
Output — Confirms credentials saved and shows the resolved base URL.
Endpoint — (local, affects Authorization header)
Clear stored credentials and revert to mock mode.
/logout
/logout
Output — Confirms credentials removed.
Endpoint — (local)
View or update individual configuration keys. Changes are persisted to ~/.gleancode/config.json.
/config [get <key> | set <key> <value> | list]
| Subcommand | Description |
|---|---|
list |
Print the full config as key/value pairs. |
get <key> |
Print the value of a single key. |
set <key> <value> |
Update a key. See the Config keys section for valid keys and values. |
/config list
/config get mode
/config set mode live
/config set default_page_size 20
/config set indexing_token glean_idx_xxx
Output — For list and get: the value(s). For set: a confirmation message.
Endpoint — (local, ~/.gleancode/config.json)
Quickly switch the API mode without editing config.
/mode <live|mock|auto>
| Value | Description |
|---|---|
live |
Force all API calls to the real Glean backend. |
mock |
Force all calls to return local fake data (no network). |
auto |
Use live if credentials are present, otherwise fall back to mock. |
/mode auto
/mode mock
/mode live
Output — Confirms the new mode.
Endpoint — (local)
Show commands entered during the current session.
/history [--limit <n>]
| Parameter | Description |
|---|---|
--limit |
Maximum number of entries to show. Default 20. |
/history
/history --limit 5
Output — A numbered list of recent commands, newest last.
Endpoint — (local)
Clear the terminal screen.
/clear
/clear
Endpoint — (local)
Quit Glean Code.
/exit
/exit
Endpoint — (local)
Send a message to the Glean Assistant. Continues the current thread by default; use --new to start a fresh conversation.
/chat <message> [--new] [--chat-id <id>] [--agent <name>] [--stream]
| Parameter | Description |
|---|---|
message |
The user message. Quote it if it contains spaces. |
--new |
Start a new chat thread, discarding the current thread id. |
--chat-id |
Continue a specific chat thread by id. |
--agent |
Route the turn through a named agent configuration. |
--stream |
Request a streaming response. |
/chat "what did engineering ship last week?"
/chat "summarise the Q2 plan" --new
/chat "draft an email to Alice" --agent sales
Output — The assistant's response in a styled box, with cited source documents listed below. The active chat thread id is saved for subsequent /chat calls.
Endpoint — POST /rest/api/v1/chat
Search the Glean index and display ranked results with snippets.
/search <query> [--page-size <n>] [--datasource <name>]
| Parameter | Description |
|---|---|
query |
Free-text search query. |
--page-size |
Number of results to return. Defaults to default_page_size in config. |
--datasource |
Restrict results to one datasource, e.g. gdrive, slack, jira, confluence. |
/search "quarterly planning"
/search "oncall runbook" --datasource confluence --page-size 5
Output — Numbered result list, each showing title, datasource, URL, and a matching text snippet.
Endpoint — POST /rest/api/v1/search
List all datasources visible to the current token, derived from a faceted search call.
/datasources.list [--with-counts] [--with-status] [--sample <n>]
| Parameter | Description |
|---|---|
--with-counts |
Show document counts per datasource. |
--with-status |
Fetch full indexing status per datasource (requires indexing_token). |
--sample |
Sample size for the underlying search call. Default 100. |
/datasources.list
/datasources.list --with-counts
/datasources.list --with-status
/datasources.list --with-counts --sample 200
Output — A list of datasource names. With --with-counts: document counts alongside each name. With --with-status: uploaded/indexed counts and coverage % from the Indexing API.
Endpoint — POST /rest/api/v1/search (facets) + POST /api/index/v1/debug/{ds}/status
Get query suggestions for a partial search string.
/autocomplete <partial>
| Parameter | Description |
|---|---|
partial |
The in-progress query string. |
/autocomplete "quart"
/autocomplete "onboard"
Output — A list of suggested completions ranked by relevance.
Endpoint — POST /rest/api/v1/autocomplete
Get document recommendations for a user based on their activity and context.
/recommendations [--user <email>]
| Parameter | Description |
|---|---|
--user |
Target user email. Defaults to the authenticated user. |
/recommendations
/recommendations --user alice@acme.com
Output — A list of recommended document titles and URLs.
Endpoint — POST /rest/api/v1/recommendations
Send explicit feedback on a search result or chat turn using its tracking token.
/feedback <tracking-token> <rating> [--comment <text>]
| Parameter | Description |
|---|---|
tracking-token |
The trackingToken field returned in a search result or chat response. |
rating |
THUMBS_UP or THUMBS_DOWN. |
--comment |
Optional free-text comment. |
/feedback tok_1 THUMBS_UP
/feedback tok_1 THUMBS_DOWN --comment "wrong datasource"
Output — Confirmation that feedback was recorded.
Endpoint — POST /rest/api/v1/feedback
Show full indexing status for a single datasource: visibility, document upload and index counts, coverage percentage, and the last five processing events.
Requires indexing_token — set it with /config set indexing_token <token>.
/datasources.status <datasource>
| Parameter | Description |
|---|---|
datasource |
Datasource name, e.g. slack, gdrive, confluence. |
/datasources.status slack
/datasources.status gdrive
Output — Datasource visibility, uploaded document count, indexed document count, coverage %, and a table of the last 5 processing history events with timestamps.
Endpoint — POST /api/index/v1/debug/{datasource}/status
Rotate the indexing API token secret and print the new raw secret. Store it immediately — the old secret is invalidated.
/indexing.rotate-token
/indexing.rotate-token
Output — The new raw secret and a reminder to run /config set indexing_token <new-secret>.
Endpoint — POST /api/index/v1/rotatetoken
List agents available to the authenticated user.
/agents.list [--query <text>]
| Parameter | Description |
|---|---|
--query |
Filter agents by name or description. |
/agents.list
/agents.list --query sales
Output — A table of agent ids, names, and descriptions.
Endpoint — POST /rest/api/v1/agents/search
Run an agent by id and wait for its final output.
/agents.run <agent-id> <input> [--stream]
| Parameter | Description |
|---|---|
agent-id |
The agent id from /agents.list. |
input |
Free-text task description or prompt for the agent. |
--stream |
Use the streaming endpoint instead of waiting for the full response. |
/agents.run agt_research "write a market brief on AI in banking"
/agents.run agt_sales "summarise account Acme Corp" --stream
Output — The agent's final response in a styled box.
Endpoint — POST /rest/api/v1/agents/runs/wait (or /stream)
List callable tools exposed to agents in the current workspace.
/tools.list
/tools.list
Output — Tool names and descriptions.
Endpoint — POST /rest/api/v1/tools/list
Invoke a tool directly with a JSON argument object.
/tools.call <name> <json-args>
| Parameter | Description |
|---|---|
name |
Tool name from /tools.list. |
json-args |
JSON object of arguments. Wrap in single quotes to preserve double quotes. |
/tools.call search '{"query":"pto policy"}'
/tools.call create_doc '{"title":"Draft","body":"Hello world"}'
Output — The tool's raw result object printed as formatted JSON.
Endpoint — POST /rest/api/v1/tools/call
Fetch one or more documents by Glean document id or URL.
/docs.get [--id <id>]... [--url <url>]...
| Parameter | Description |
|---|---|
--id |
Glean document id. Repeatable. |
--url |
Document URL. Repeatable. |
/docs.get --id doc_123 --id doc_456
/docs.get --url https://docs.acme.com/plan
Output — Document metadata and content for each requested id or URL.
Endpoint — POST /rest/api/v1/getdocuments
Fetch the permission list for a document.
/docs.permissions <doc-id>
| Parameter | Description |
|---|---|
doc-id |
Glean document id. |
/docs.permissions doc_123
Output — A list of email addresses and their roles (e.g. owner, viewer).
Endpoint — POST /rest/api/v1/getdocumentpermissions
List entities such as people, teams, or groups from the Glean directory.
/entities.list [--kind PEOPLE|TEAM|GROUP] [--page-size <n>] [--query <text>]
| Parameter | Description |
|---|---|
--kind |
Entity type. Default PEOPLE. |
--page-size |
Number of results. Defaults to default_page_size in config. |
--query |
Optional filter string matched against name. |
/entities.list
/entities.list --kind TEAM
/entities.list --kind PEOPLE --query alice
Output — A list of entity names, emails, and titles.
Endpoint — POST /rest/api/v1/listentities
Look up a person's full profile by email address.
/people.get <email>
| Parameter | Description |
|---|---|
email |
The person's email address. |
/people.get alice@acme.com
Output — Name, email, title, department, and any other profile fields returned by the API.
Endpoint — POST /rest/api/v1/people
List all current announcements in the workspace.
/announcements.list
/announcements.list
Output — Announcement ids, titles, and metadata.
Endpoint — POST /rest/api/v1/announcements/list
Create a new workspace announcement.
/announcements.create --title <text> --body <text> [--audience <filter>]
| Parameter | Description |
|---|---|
--title |
Headline for the announcement. |
--body |
Main body text. |
--audience |
Optional audience filter string to target a subset of users. |
/announcements.create --title "All hands Friday" --body "10am PT, Zoom link in calendar"
/announcements.create --title "System maintenance" --body "Sunday 2am–4am PT" --audience engineering
Output — The new announcement id and creation status.
Endpoint — POST /rest/api/v1/announcements/create
Delete an announcement by id.
/announcements.delete <id>
| Parameter | Description |
|---|---|
id |
The announcement id (from /announcements.list). |
/announcements.delete ann_123
Output — Confirms the announcement was deleted.
Endpoint — POST /rest/api/v1/announcements/delete
List all collections in the workspace.
/collections.list
/collections.list
Output — Collection ids, names, and descriptions.
Endpoint — POST /rest/api/v1/listcollections
Create a new collection for grouping related documents.
/collections.create --name <text> [--description <text>]
| Parameter | Description |
|---|---|
--name |
Collection name. |
--description |
Optional description. |
/collections.create --name Onboarding
/collections.create --name Onboarding --description "New hire docs and links"
Output — The new collection id and name.
Endpoint — POST /rest/api/v1/createcollection
List all pinned results in the workspace.
/pins.list
/pins.list
Output — Pin ids, queries they are attached to, and target URLs.
Endpoint — POST /rest/api/v1/listpins
Pin a URL to a search query so it appears as the top result for that query.
/pins.create --query <text> --url <url>
| Parameter | Description |
|---|---|
--query |
The search query to attach the pin to. |
--url |
The URL to surface as the pinned result. |
/pins.create --query pto --url https://hr.acme.com/pto
/pins.create --query "expense policy" --url https://wiki.acme.com/expenses
Output — The new pin id and creation status.
Endpoint — POST /rest/api/v1/createpin
Generate a self-contained Python starter project for a Glean API surface. Credentials are read from ~/.gleancode/config.json so the generated file works immediately. Generated files are stdlib-only.
/scaffold <chat|search|agent> [--output <dir>]
| Parameter | Description |
|---|---|
template |
Which template to generate: chat, search, or agent. |
--output |
Output directory. Prompted interactively if omitted. You will be asked to confirm before a new directory is created. |
/scaffold chat
/scaffold search --output ~/projects/glean-search
/scaffold agent --output ./my-agent-app
| Template | What it generates |
|---|---|
chat |
Interactive chat loop with single-turn CLI mode |
search |
Search script with --datasource and --page-size flags |
agent |
Lists available agents and runs one by id |
Output — Writes a single .py file to the output directory and prints the full path.
Endpoint — (local, writes a standalone .py file)
/insights retrieves aggregate usage data from the Glean Insights Dashboard — the same data visible in the admin UI. It covers search adoption, active user counts, search session satisfaction, datasource click distribution, and AI assistant activity.
Uses the same Client API token as search and chat — no extra credentials required.
| Flag | Description |
|---|---|
| (none) | Overview only: MAU, WAU, employee count, sign-ups, search satisfaction, clicks by datasource |
--assistant |
Adds Assistant metrics: MAU, WAU, chat messages, AI answers, summarizations |
--agents |
Adds Agents metrics: MAU, WAU |
--all |
All three surfaces in one call |
--no-per-user |
Suppresses the per-user breakdown in the response |
/insights
/insights --all
/insights --assistant
/insights --agents --no-per-user
- Monthly and weekly active users
- Employee count and total sign-ups (from org chart)
- Search session satisfaction rate (%)
- Last updated timestamp
- Search clicks broken down by datasource (gdrive, confluence, slack, jira, etc.)
- Monthly and weekly active users of the Glean Assistant
- Chat message, AI answer, and summarization activity
- Monthly and weekly active users across agent runs
POST /rest/api/v1/insights
/datasources.list --with-status enriches each datasource with live indexing data from the Glean Indexing API. /datasources.status <name> shows the full status for a single datasource including document counts and recent processing events.
These commands require an indexing token. Obtain one from your Glean admin UI (workspace settings → API tokens → Indexing), then store it:
/config set indexing_token <token>
| Command | Description |
|---|---|
/datasources.list --with-status |
Lists all datasources with uploaded/indexed counts and coverage |
/datasources.status <name> |
Full status for one datasource: visibility, counts, last 5 processing events |
/indexing.rotate-token |
Rotates your indexing token secret and prints the new raw secret |
Example:
/datasources.status slack
/datasources.list --with-status
/indexing.rotate-token
After rotating a token, store the new secret immediately:
/config set indexing_token <new-raw-secret>
/scaffold generates a self-contained Python starter file for a Glean API surface. It reads credentials from your existing ~/.gleancode/config.json (written by /login) so the generated script works immediately.
/scaffold chat # interactive chat loop + single-turn CLI
/scaffold search # search with --datasource and --page-size flags
/scaffold agent # list agents and run them by id
Each template accepts an output directory. If omitted you are prompted, and if the directory does not exist you are asked before it is created.
/scaffold chat --output ~/projects/my-chat-app
The generated files are stdlib-only — no pip install required. They also support GLEAN_INSTANCE, GLEAN_TOKEN, and GLEAN_ACT_AS environment variables as an alternative to the config file.
| Key | Description | Values |
|---|---|---|
instance |
Glean backend host | e.g. acme-be.glean.com |
api_token |
Client API bearer token | Glean-issued token |
indexing_token |
Indexing API token (for datasource status) | Glean-issued token |
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 |
Change any key with /config set <key> <value>. Use /mode live|mock|auto to force a mode without editing config.
glean-code/
glean-code launcher script
glean_mcp.py MCP server entry point
glean_code/
__init__.py
__main__.py python -m glean_code
cli.py REPL loop and banner
ui.py ASCII art, colours, boxes
config.py config file load and save
client.py Glean REST wrapper + mock responses
commands.py slash command parser and handlers
help_docs.py per-command documentation
completion.py readline tab completion
scaffold.py project scaffold templates
tests/
__init__.py
test_client.py GleanClient and mock response tests
test_config.py Config load, save and URL property tests
test_ui.py ANSI helpers, box renderer and status bar tests
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.
Install the MCP package (one-time):
pip
pip install "mcp[cli]"brew
brew install pipx
pipx install "mcp[cli]"Claude Code — add to .claude/settings.json in your project, or to
~/.claude/settings.json globally:
{
"mcpServers": {
"glean": {
"command": "python3",
"args": ["/absolute/path/to/glean-code-cli/glean_mcp.py"]
}
}
}Claude Desktop — add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"glean": {
"command": "python3",
"args": ["/absolute/path/to/glean-code-cli/glean_mcp.py"]
}
}
}Cursor — add to .cursor/mcp.json in your project:
{
"mcpServers": {
"glean": {
"command": "python3",
"args": ["/absolute/path/to/glean-code-cli/glean_mcp.py"]
}
}
}Credentials are loaded automatically from ~/.gleancode/config.json (written
by /login in the REPL). You can also pass them as environment variables:
{
"mcpServers": {
"glean": {
"command": "python3",
"args": ["/absolute/path/to/glean-code-cli/glean_mcp.py"],
"env": {
"GLEAN_INSTANCE": "your-instance-be.glean.com",
"GLEAN_TOKEN": "your-token"
}
}
}
}Tools exposed:
| Tool | Description |
|---|---|
search |
Search the Glean index; optional datasource and page_size |
chat |
Chat with the Glean Assistant; pass chat_id to continue a thread |
list_agents |
List available agents; optional query filter |
run_agent |
Run an agent by id and return its output |
Requires Python 3.10+. The REPL itself remains Python 3.9+ and stdlib-only.
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/| File | What it covers |
|---|---|
tests/test_client.py |
All mock responses, GleanClient methods, error handling |
tests/test_config.py |
Config load/save, URL property computation, mode resolution |
tests/test_ui.py |
ANSI width helpers, box renderer, status bar, hyperlink |
The client targets the documented Glean Client REST API at https://<instance>-be.glean.com/rest/api/v1. Paths used:
POST /chat
POST /search
POST /autocomplete
POST /recommendations
POST /feedback
POST /agents/search
POST /agents/runs/wait
POST /agents/runs/stream
POST /tools/list
POST /tools/call
POST /getdocuments
POST /getdocumentpermissions
POST /listentities
POST /people
POST /announcements/list
POST /announcements/create
POST /announcements/delete
POST /listcollections
POST /createcollection
POST /listpins
POST /createpin
POST /insights
Indexing API paths (require a separate indexing token, base https://<instance>-be.glean.com/api/index/v1):
POST /api/index/v1/debug/{datasource}/status
POST /api/index/v1/rotatetoken
If your tenant uses a slightly different path for a given surface, change it in glean_code/client.py. Every method is a small wrapper around self._post(path, body) so the swap is a one-liner.
Wrap the JSON in single quotes so the shell parser leaves the double quotes intact:
/tools.call search '{"query":"pto policy"}'
