Summary
When gbrain init --mcp-only configures thin-client mode, most CLI commands (search, query, think, salience, stats, get, put, list, tags, graph, timeline, etc.) silently fall through to the empty local PGLite database and return zero results. No error, no warning — just "No results." or empty output.
Only 9 commands are in THIN_CLIENT_REFUSED_COMMANDS:
sync, embed, extract, migrate, apply-migrations, repair-jsonb, orphans, integrity, serve
Meanwhile ~20+ operation-based commands happily connect to the local empty DB and produce misleading output.
This is a terrible first experience for any agent or human using thin-client mode. You run gbrain search "something you know is in the brain" and get nothing back, with no indication anything is wrong.
Reproduction
# On a thin-client install (gbrain init --mcp-only)
gbrain search "any query"
# → runs 38 migrations on local PGLite, returns "No results."
gbrain stats
# → Pages: 0, Chunks: 0, Embedded: 0 (the remote brain has 102k pages)
gbrain salience
# → "(no pages touched in the salience window)"
gbrain think "what is garry working on"
# → "no LLM available" + 0 pages gathered (doesn't even try MCP)
gbrain query "test"
# → "No results." (should have hit 100k+ pages on remote)
All of these return as if they succeeded. Exit code 0, no errors. The user has no idea they're hitting an empty local database instead of the remote brain.
Root Cause
In src/cli.ts, THIN_CLIENT_REFUSED_COMMANDS is a deny-list of 9 commands. Everything else passes through to connectEngine() which opens the local PGLite — empty, because thin-client mode intentionally skips local sync/embed.
const THIN_CLIENT_REFUSED_COMMANDS = new Set([
'sync', 'embed', 'extract', 'migrate', 'apply-migrations',
'repair-jsonb', 'orphans', 'integrity', 'serve',
]);
The operation-based commands (search, query, think, salience, stats, get, put, list, tags, graph, timeline, health, history, backlinks, etc.) are all missing from this set.
Proposed Fix (two tiers)
Tier 1 (quick fix): Flip to an allowlist
Instead of denying specific commands, only allow the few that make sense locally:
const THIN_CLIENT_LOCAL_COMMANDS = new Set([
'init', 'remote', 'doctor', 'auth', 'config',
'upgrade', 'post-upgrade', 'check-update',
]);
// In handleCliOnly():
if (!THIN_CLIENT_LOCAL_COMMANDS.has(command)) {
const cfg = loadConfig();
if (isThinClient(cfg)) {
const url = cfg!.remote_mcp!.mcp_url;
console.error(
`\`gbrain ${command}\` requires a local engine. This install is a thin client of ${url}.\n` +
`Use the corresponding MCP tool from your agent, or run \`${command}\` on the remote host.`
);
process.exit(1);
}
}
This prevents silent wrong results immediately.
Tier 2 (better UX): Route CLI commands through MCP when in thin-client mode
When isThinClient(cfg) is true, commands like gbrain search X should proxy to the remote MCP search tool instead of hitting local DB. The thin-client config already has OAuth credentials and the MCP URL — the plumbing is there.
gbrain search "separation"
# thin-client detected → OAuth token mint → POST /mcp tools/call search → display results
This makes the CLI "just work" regardless of topology. The mapping is straightforward since most CLI commands have 1:1 MCP tool equivalents:
| CLI command |
MCP tool |
search |
search |
query |
query |
think |
think |
get |
get_page |
put |
put_page |
stats |
get_stats |
health |
get_health |
salience |
❌ no MCP tool (see note) |
anomalies |
❌ no MCP tool |
tags |
get_tags |
backlinks |
get_backlinks |
graph |
traverse_graph |
timeline |
get_timeline |
list |
list_pages |
Bonus: Missing MCP tools
salience and anomalies are CLI-only — no MCP equivalents exist. These are arguably the highest-value synthesis tools for agents (salience = "what matters right now?", anomalies = "what's weird?"). Adding them as MCP tools would close the parity gap.
Context
This was discovered by Hermes Agent (Neuromancer) running as a thin client of a gbrain instance on wintermute. The agent configured gbrain init --mcp-only, then attempted to use CLI commands before realizing they were all hitting an empty local DB. The MCP tools work perfectly — the issue is purely the CLI dispatch layer not respecting thin-client mode for most commands.
Environment
- gbrain v0.29.2
- Thin-client mode via
gbrain init --mcp-only
- Remote: wintermute running gbrain serve (102k pages, 265k chunks)
- Client: Railway container (Linux)
Summary
When
gbrain init --mcp-onlyconfigures thin-client mode, most CLI commands (search,query,think,salience,stats,get,put,list,tags,graph,timeline, etc.) silently fall through to the empty local PGLite database and return zero results. No error, no warning — just "No results." or empty output.Only 9 commands are in
THIN_CLIENT_REFUSED_COMMANDS:Meanwhile ~20+ operation-based commands happily connect to the local empty DB and produce misleading output.
This is a terrible first experience for any agent or human using thin-client mode. You run
gbrain search "something you know is in the brain"and get nothing back, with no indication anything is wrong.Reproduction
All of these return as if they succeeded. Exit code 0, no errors. The user has no idea they're hitting an empty local database instead of the remote brain.
Root Cause
In
src/cli.ts,THIN_CLIENT_REFUSED_COMMANDSis a deny-list of 9 commands. Everything else passes through toconnectEngine()which opens the local PGLite — empty, because thin-client mode intentionally skips local sync/embed.The operation-based commands (
search,query,think,salience,stats,get,put,list,tags,graph,timeline,health,history,backlinks, etc.) are all missing from this set.Proposed Fix (two tiers)
Tier 1 (quick fix): Flip to an allowlist
Instead of denying specific commands, only allow the few that make sense locally:
This prevents silent wrong results immediately.
Tier 2 (better UX): Route CLI commands through MCP when in thin-client mode
When
isThinClient(cfg)is true, commands likegbrain search Xshould proxy to the remote MCPsearchtool instead of hitting local DB. The thin-client config already has OAuth credentials and the MCP URL — the plumbing is there.This makes the CLI "just work" regardless of topology. The mapping is straightforward since most CLI commands have 1:1 MCP tool equivalents:
searchsearchqueryquerythinkthinkgetget_pageputput_pagestatsget_statshealthget_healthsalienceanomaliestagsget_tagsbacklinksget_backlinksgraphtraverse_graphtimelineget_timelinelistlist_pagesBonus: Missing MCP tools
salienceandanomaliesare CLI-only — no MCP equivalents exist. These are arguably the highest-value synthesis tools for agents (salience = "what matters right now?", anomalies = "what's weird?"). Adding them as MCP tools would close the parity gap.Context
This was discovered by Hermes Agent (Neuromancer) running as a thin client of a gbrain instance on wintermute. The agent configured
gbrain init --mcp-only, then attempted to use CLI commands before realizing they were all hitting an empty local DB. The MCP tools work perfectly — the issue is purely the CLI dispatch layer not respecting thin-client mode for most commands.Environment
gbrain init --mcp-only