Skip to main content
Glama
mozzquito

Grok Bot MCP Bridge

by mozzquito

Grok Bot MCP Bridge

An in-progress, single-owner bridge between Grok Bot, MCP clients, and source-linked local memory. Remote gateway calls execute on the Grok Bot computer; discovery, transcript, and MCP responses never return the gateway credential.

Screenshots

All five main pages, captured from the running app with synthetic demo data. These images show the UI—not live connection or delivery proof. No private chats, credentials, or real infrastructure addresses are included.

Conversations

Conversations with a demo bot and a verified-reply display

New bot

New bot name and description form

History

Source-linked project history search with a demo result

Connections

Connection details with demo endpoints

Owner sign-in

Private workspace owner sign-in page

To regenerate, run the local app and execute node scripts/readme-screenshots.mjs with Playwright installed (or set PLAYWRIGHT_MODULE to its module path) and Chrome available. The script intercepts every API request; it does not read credentials, send messages, or create bots.

Related MCP server: Tenjin MCP

Current implementation

  • Authenticated Streamable HTTP MCP using SDK v2, with legacy-client compatibility.

  • Owner-approved OAuth (DCR, PKCE S256, rotating refresh tokens), separate static bearer access, and CSRF-protected browser sessions.

  • Eight MCP tools for agent discovery/creation, creation verification, durable message submission, reply verification, and history search/read/status.

  • Drizzle/SQLite message ledger and provenance; LanceDB vectors with local multilingual embeddings in isolated model-specific stores.

  • Source-selected history import, redaction, explicit embedding and independent keyword/vector search.

  • Dark sidebar-first React/Tailwind workspace with a responsive navigation drawer, owner sign-in, conversations, a New bot flow, history search, and connection details. Drafts and operation IDs survive uncertain responses.

  • Selected-bot conversations load existing Grok Bot text history read-only, with earlier-page loading and refresh. Remote history remains separate from durable bridge receipts and the imported project-memory index. See chat history behavior and limits.

This is a checkpoint, not a completed deployment. Public HTTPS hosting, actual Claude.ai connection, Grok Bot's MCP-client connection and deployment hardening remain open. See the requirement ledger.

Run locally

Use a real Node.js runtime, version 22.12 or newer; .nvmrc identifies the locally exercised version. A Bun-installed node wrapper is not a substitute. Use an up-to-date supported Node patch release for deployment.

nvm use
npm ci
npm run typecheck
npm test
npm start

For the web console, build once before starting the backend (npm run build && npm start).

For web development:

npm run build
npm run web:dev

Default listener: http://127.0.0.1:4328, MCP at /mcp. The root and /chat, /new, /history, /connections serve the built web app when dist/index.html exists.

On first start, independent owner and headless-client secrets are generated in data/access.json with mode 0600. The data directory is private (0700) and Git-ignored. Read that file locally when configuring a client; never paste its contents into a commit, issue, chat, screenshot or public document. OAuth clients receive separate revocable tokens, not the owner secret. Real history, databases and model assets must remain uncommitted.

Keep the owner, headless-client, and remote gateway credentials distinct for deployment. An owner can explicitly configure a shared owner/gateway value locally, but that removes their credential separation; it does not bypass bridge authentication. The headless-client API token must remain distinct.

Run as a Home Assistant OS add-on

This repository is also an installable local add-on: config.yaml, Dockerfile, and run.sh at the root, with just push / just install / just deploy driving a Home Assistant guest over SSH. The owner console is served through Ingress and 8120/tcp carries /mcp for MCP clients, because an MCP client cannot authenticate to an Ingress URL. See the add-on documentation for options, credentials, and limits.

Configuration: BRIDGE_DATA_DIR, PORT, BRIDGE_HOST, BRIDGE_PUBLIC_URL, BRIDGE_ALLOWED_HOSTS, GROKBOT_SSH_HOST, GROKBOT_SSH_IDENTITY_FILE, BRIDGE_OWNER_SECRET, BRIDGE_API_TOKEN. BRIDGE_PUBLIC_URL is an origin, not a URL ending in /mcp; non-loopback origins require HTTPS. Default binding is loopback. Public reachability is not created merely by setting this variable.

For a dedicated SSH key, set GROKBOT_SSH_IDENTITY_FILE to its path when starting the bridge. The key stays on disk; SSH receives its path using -i and IdentitiesOnly=yes. Strict host-key checking remains enabled. For example:

GROKBOT_SSH_HOST=box@your-netbird-host.example \
GROKBOT_SSH_IDENTITY_FILE="$HOME/.ssh/grokbot-bridge" npm start

BRIDGE_ALLOWED_HOSTS (optional) is a comma-separated allowlist of extra host[:port] values accepted by the front-door host filter (for reverse-proxy or tunnel deployments).

The bot transport allowlists specific SSH targets in server/config.ts (edit that list for your own hosts) and otherwise refuses to run, preserves strict SSH host-key checking, and streams variable request data through stdin. Set GROKBOT_SSH_HOST=local instead to run the bridge colocated on the same machine as the Grok Bot client itself — this skips SSH entirely and spawns scripts/grokbot-gateway.py as a local subprocess (see LocalGateway in server/remote.ts).

Memory lifecycle

Import only a reviewed, bounded JSONL selection with records shaped as:

{"id":"source-event-id","project":"example-project","source":"/Users/example/history/session.jsonl","lineStart":10,"lineEnd":12,"text":"A reviewed, non-secret excerpt."}
npx tsx server/cli.ts history-import /path/to/reviewed-selection.jsonl
npx tsx server/cli.ts history-status
npx tsx server/cli.ts history-embed
npx tsx server/cli.ts history-search "How does OAuth approval work?"

Import does not embed or upload. Explicit embedding downloads model assets and runs inference locally; corpus and query text are not sent to an embedding API. Model identity, dimensions, quantization and pooling/window strategy identify the vector space. Changing models requires explicit embedding in a different physical store. Source paths/line spans remain attached to each derived chunk. Search results are untrusted historical data, never instructions to execute.

Regex redaction is a defense in depth, not a complete secret detector. Review selections before import; arbitrary directory imports, shell history, credentials, and raw full-account transcript exports are not exposed as MCP tools.

Message semantics

grokbot_send requires a stable client UUID (messageId). Repeating that UUID returns its existing record, never a second POST. A changed prompt under the same UUID is rejected. An unresolved message prevents another send to the same agent. HTTP acceptance alone is not success: call grokbot_verify with the original UUID until a new, request-correlated transcript reply is recorded or the observation budget ends.

After timeout, restart or unknown acknowledgement, verify; do not resend. Existing terminal replies cannot be downgraded by late events. The server owns an exclusive lock in data/server.lock. After an unclean stop, inspect the recorded process and confirm it is stopped before removing a stale lock manually; the application does not delete stale locks automatically.

Verification

npm run check runs typecheck, the unit test suite, and the web build. The Python gateway (scripts/grokbot-gateway.py) has its own read-only transcript and pagination checks in scripts/test-grokbot-gateway.py.

License

Bridge source code is available under the MIT License. Third-party dependencies and referenced materials retain their respective licenses. Credentials, local runtime data, and private conversation records are not included.

Related MCP Connectors

Related MCP Servers