Skip to content

feat: GBrain v0.6.0 — Remote MCP Server + 12 Bug Fixes#28

Merged
garrytan merged 14 commits intomasterfrom
garrytan/v0.6-mcp-server
Apr 11, 2026
Merged

feat: GBrain v0.6.0 — Remote MCP Server + 12 Bug Fixes#28
garrytan merged 14 commits intomasterfrom
garrytan/v0.6-mcp-server

Conversation

@garrytan
Copy link
Copy Markdown
Owner

Summary

Remote MCP Server — deploy GBrain as a serverless endpoint on your existing Supabase instance. Your personal knowledge brain follows you across Claude Desktop, Claude Code, Cowork, and Perplexity Computer. Zero new infrastructure.

12 Bug Fixes — every critical bug from Issue #22 and Issue #9 addressed:

  • MCP handler registration (server was silently broken)
  • Search quality (keyword floods, dedup collapse)
  • Data integrity (embed wipes embeddings, transaction corruption, import checkpoint race)
  • Storage (S3 auth, file_upload never uploading, redirect data loss)
  • Consistency (slug normalization, dry_run ignored, initSchema disk reads)

Per-client docs — setup guides for Claude Code, Claude Desktop, Cowork, Perplexity, plus ChatGPT (coming soon, requires OAuth 2.1) and Tailscale/ngrok alternatives.

Commits

Test Coverage

232 pass, 0 fail across 352 tests (25 files). E2E tests skip gracefully without DATABASE_URL.

Reviews

Review Status Findings
CEO Review CLEAR 5 scope expansions accepted
DX Review CLEAR Score 5→7/10, TTHW 3min
Eng Review (x2) CLEAR config.ts lazy eval, tx scoped engine, upsertChunks root cause
Codex (x2) CLEAR 15 findings resolved, 6 fixes broadened

Key DX Findings

  • ChatGPT requires OAuth 2.1 for MCP (bearer tokens not supported). Dropped from v1, tracked as P0 TODO.
  • Claude Desktop remote MCP uses Settings > Integrations, NOT claude_desktop_config.json.
  • Claude Cowork has a local bridge via Claude Desktop SDK layer.

TODOS

  • S3 Sig V4 TODO marked complete (replaced with @aws-sdk/client-s3)
  • Added: ChatGPT OAuth 2.1 (P0), Fly.io alternative deployment (P2)

Test plan

  • All unit tests pass (232 pass, 0 fail)
  • Edge Function bundle builds successfully (585KB)
  • Per-client docs cover Claude Code, Desktop, Cowork, Perplexity, ChatGPT
  • E2E tests (require DATABASE_URL, run in CI)

🤖 Generated with Claude Code

garrytan and others added 10 commits April 10, 2026 07:37
- fix(mcp): use ListToolsRequestSchema/CallToolRequestSchema instead of string literals (Issue #9, PR #25)
- fix(mcp): handleToolCall reads dry_run from params instead of hardcoding false (#22 Bug #11)
- fix(search): keyword search returns best chunk per page via DISTINCT ON, not all chunks (#22 Bug #8)
- fix(search): dedup layer 1 keeps top 3 chunks per page instead of collapsing to 1 (#22 Bug #12)
- fix(engine): transaction uses scoped engine via Object.create, no shared state mutation (#22 Bug #2)
- fix(engine): upsertChunks uses UPSERT instead of DELETE+INSERT, preserves existing embeddings (#22 Bug #1)
- fix(slugs): validateSlug normalizes to lowercase, pathToSlug lowercases consistently (#22 Bug #4)
- schema: add unique index on content_chunks(page_id, chunk_index) for UPSERT support
- schema: add access_tokens and mcp_request_log tables via migration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…hema

initSchema() previously read schema.sql from disk at runtime via readFileSync,
which broke in compiled Bun binaries and Deno Edge Functions. Now uses a
generated schema-embedded.ts constant (run `bun run build:schema` to regenerate).

- Removes fs and path imports from postgres-engine.ts and db.ts
- Adds scripts/build-schema.sh for one-source-of-truth generation
- Adds build:schema npm script

Fixes Issue #22 Bug #6.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- fix(file_upload): call storage.upload() in all 3 paths (operation, CLI upload, CLI sync) with rollback semantics (#22 Bug #9)
- fix(import): use atomic index counter for parallel queue instead of array.shift() race, preserve checkpoint on errors (#22 Bug #3)
- fix(s3): replace unsigned fetch with @aws-sdk/client-s3 for proper SigV4 auth, supports R2/MinIO via forcePathStyle (#22 Bug #10)
- fix(redirect): verify remote file exists before deleting local copy, skip files not found in storage (#22 Bug #5)
- deps: add @aws-sdk/client-s3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deploy GBrain as a serverless remote MCP endpoint on your existing Supabase
instance. One brain, accessible from Claude Desktop, Claude Code, Cowork,
Perplexity Computer, and any MCP client. Zero new infrastructure.

New files:
- supabase/functions/gbrain-mcp/index.ts — Edge Function with Hono + MCP SDK
- supabase/functions/gbrain-mcp/deno.json — Deno import map
- src/edge-entry.ts — curated bundle entry point (excludes fs-dependent modules)
- src/commands/auth.ts — standalone token management (create/list/revoke/test)
- scripts/deploy-remote.sh — one-script deployment
- .env.production.example — 3-value config template

Changes:
- config.ts: lazy-evaluate CONFIG_DIR (no homedir() at module scope)
- schema.sql: add access_tokens + mcp_request_log tables
- package.json: add build:edge script

Auth: bearer tokens via access_tokens table (SHA-256 hashed, per-client, revocable)
Transport: WebStandardStreamableHTTPServerTransport (stateless, Streamable HTTP)
Health: /health endpoint (unauth: 200/503, auth: postgres/pgvector/openai checks)
Excluded from remote: sync_brain, file_upload (may exceed 60s timeout)

Setup: clone, fill .env.production, run scripts/deploy-remote.sh, create token, done.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- docs/mcp/DEPLOY.md — deployment walkthrough, auth, troubleshooting, latency table
- docs/mcp/CLAUDE_CODE.md — claude mcp add command
- docs/mcp/CLAUDE_DESKTOP.md — Settings > Integrations (NOT JSON config!)
- docs/mcp/CLAUDE_COWORK.md — remote + local bridge paths
- docs/mcp/PERPLEXITY.md — Perplexity Computer connector setup
- docs/mcp/CHATGPT.md — coming soon (requires OAuth 2.1, P0 TODO)
- docs/mcp/ALTERNATIVES.md — Tailscale Funnel + ngrok self-hosted options

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GBrain v0.6.0: Remote MCP server via Supabase Edge Functions + 12 bug fixes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Post-ship requirements section: document-release is NOT optional. Lists every
file that must be checked on every ship. A ship without updated docs is incomplete.

Also adds remote MCP server files to Key files section.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The per-chunk UPSERT loop caused deadlocks under parallel workers because
each INSERT ON CONFLICT acquired row-level locks sequentially. Multiple
workers upserting different pages could deadlock on the shared unique index.

Fix: batch all chunks into a single multi-row INSERT ON CONFLICT statement.
One round-trip, one lock acquisition. COALESCE preserves existing embeddings
when the new value is NULL.

Fixes CI failure: "E2E: Parallel Import > parallel import with --workers 4"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
garrytan and others added 4 commits April 10, 2026 11:09
…erver

Resolved conflicts:
- VERSION: keep 0.6.0
- CHANGELOG.md: keep both 0.6.0 and 0.5.1 entries in order
- src/core/migrate.ts: renumber migrations (master's v2 slugify first, then v3 unique_chunk_index, v4 access_tokens)
- test/sync.test.ts: keep our test name ('normalizes to lowercase')
When multiple processes call initSchema() concurrently (e.g., test setup +
CLI subprocess, or parallel workers during E2E tests), the schema SQL's
DROP TRIGGER + CREATE TRIGGER statements acquire AccessExclusiveLock on
different tables, causing deadlocks.

Fix: pg_advisory_lock(42) serializes all initSchema() calls within the
same database. The lock is session-scoped and released in a finally block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CLI subprocess tests (Setup Journey, Doctor Command, Parallel Import)
spawn `bun run src/cli.ts` which takes several seconds to JIT compile +
connect. The Bun test framework default 5000ms per-test timeout is too
tight for CI. Added 30-60s timeouts matching each subprocess's own
timeout to prevent false failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The replace_all refactor created recursive functions: the exported
getConfigDir() called the private getConfigDir() which called itself.
Renamed exports to configDir()/configPath() to avoid shadowing.

Also adds scripts/smoke-test-mcp.ts — verified all 8 MCP tool calls
work against a real Postgres database.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@garrytan garrytan merged commit 3e21e9b into master Apr 11, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant