v0.3.84 97ae0a2

README.md RawHistoryFolder

mcp-bridge

Connect zot to MCP (Model Context Protocol) servers.

This extension reads MCP server configurations from standard locations (same format as Claude Desktop, Cursor, Cline, etc.) and bridges their tools into zot so the LLM can call them directly.

Features

  • Standard config format — same JSON as Claude Desktop, Cursor, Cline
  • On-demand tool discovery — only mcp__search_tools is advertised initially; matching MCP schemas load when needed instead of bloating every model request
  • Smart lazy loading — cached definitions register as deferred tools at startup, servers wake for refresh or tool calls, then auto-sleep after idle time
  • Auto-respawn — calling a loaded tool on a sleeping server wakes it up automatically
  • Multi-transport — stdio, streamable-http, and SSE transports
  • Multi-server — connect to any number of MCP servers simultaneously
  • Tool namespacing — tools appear as mcp__<server>__<tool> to avoid collisions
  • Tool annotations — read-only, destructive, idempotent hints surfaced to LLM
  • Configurable timeouts — per-server connect, request, and idle timeouts
  • Custom headers — auth tokens and other headers for HTTP servers
  • Slash commands — /mcp to check status, start/stop/restart servers
  • Better error messages — context-aware errors with actionable suggestions

Environment variables

Like Claude Code, the bridge expands ${VAR} and ${VAR:-default} in command, args, env values, url, and headers values. This is client configuration compatibility, not a requirement of the MCP protocol.

{"mcpServers":{"api":{"transport":"streamable-http","url":"${API_BASE_URL:-https://api.example.com}/mcp","headers":{"Authorization":"Bearer ${API_KEY}"}}}}

Expansion uses the bridge process environment after global/project configurations are merged. Defaults apply to unset variables; an explicitly empty variable stays empty. Values are expanded once, without shell execution, bare $VAR expansion, nested defaults, or references to sibling env entries. Config files are not rewritten. A missing variable without a default disables that server and reports the server, field, and variable name, never the field value; other valid servers remain available.

If the project config cannot be read or parsed, the bridge reports that error and still expands and validates retained global servers. Servers with missing required variables are excluded in this case too.

Quick Start

  1. Build the extension:

    cd examples/extensions/mcp-bridge
    go build -o mcp-bridge .
    
  2. Create a project config file:

    mkdir -p .zot
    cat > .zot/mcp.json << 'EOF'
    {
      "mcpServers": {
        "filesystem": {
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
        },
        "context7": {
          "command": "npx",
          "args": ["-y", "@upstash/context7-mcp@latest"]
        }
      }
    }
    EOF
    
  3. Install the extension:

    zot ext install .
    
  4. Restart zot. On first run the extension refreshes its tool cache in the background. When zot shows MCP tool cache changed, run /reload-ext once. Future launches register the cached MCP tools immediately as deferred definitions.

The model initially sees one small loader tool, mcp__search_tools. It searches cached MCP tool names and descriptions locally, activates up to eight relevant definitions by default, and then calls the selected MCP tool normally. This keeps large MCP installations compatible with providers that limit request or tool-schema size.

Phone pairing with Build Remote Agent

Build Remote Agent is an optional, third-party integration that lets a paired phone observe terminal sessions and veto actions. It is an independent Linespotting AB product and is not affiliated with xAI or SpaceX.

Install the agent

Pin release v0.6.0 and verify the binary against the checksum listed here. The release's own SHA256SUMS file does not currently match five of its six binary assets, so do not use that file as the trust source. These checksums were verified directly against the release assets on 2026-08-24:

62673a6856342a87d4a2a659bc1de92200aa19a5b60d88d252254940820f0b7f  gbr-agent-darwin-amd64
7baa1a8e214cd71b60e3f2b5063713e00ff740939749c3cab3d702784a1432f8  gbr-agent-darwin-arm64
fb54724367882497f2e8e05e40ecdeb4be29e008e6c865fc5c426cf464e6ad6e  gbr-agent-linux-amd64
9e9d7ca45bb0c4ded9d04226136013e9b64ae30f16bcf03069d35e9c38171cb9  gbr-agent-linux-arm64
40355b2be6cd68f3be68f2a06dfd30307ec1a60f16f87f1d6174012b35aa4a49  gbr-agent-windows-amd64.exe
8fb9efcbc7e2ac91c11964944bf0f45e31bb23f4356d9dcb4b305d7cb9b0fe8c  gbr-agent-windows-arm64.exe

This macOS Apple Silicon example downloads, verifies, and installs the binary. Change both ASSET and SHA for another platform.

VER=v0.6.0
ASSET=gbr-agent-darwin-arm64
SHA=7baa1a8e214cd71b60e3f2b5063713e00ff740939749c3cab3d702784a1432f8
BASE="https://github.com/LinespottingOrg/GrokBuildRemote-Agents/releases/download/$VER"
curl -fsSL -o "$ASSET" "$BASE/$ASSET"
if command -v sha256sum >/dev/null 2>&1; then
  printf '%s  %s\n' "$SHA" "$ASSET" | sha256sum -c -
else
  printf '%s  %s\n' "$SHA" "$ASSET" | shasum -a 256 -c -
fi
mkdir -p "$HOME/.local/bin"
install -m 0755 "$ASSET" "$HOME/.local/bin/gbr-agent"
export PATH="$HOME/.local/bin:$PATH"
gbr-agent version  # must report v0.6.0
gbr-agent pair
gbr-agent run

Keep gbr-agent run running. Its Bot API should only be available over loopback:

curl -sS http://127.0.0.1:8788/health
curl -sS http://127.0.0.1:8788/v1/sessions

Install the MCP server

The MCP server requires Node.js 20 or newer. Pin its source instead of cloning the mutable default branch:

git clone --branch v0.6.0 --depth 1 https://github.com/LinespottingOrg/GrokBuildRemote-Agents.git
cd GrokBuildRemote-Agents/mcp/gbr-mcp
npm install --ignore-scripts
MCP_PATH="$(pwd)/bin/gbr-mcp.js"
node "$MCP_PATH" --diagnose

The v0.6.0 source does not include a package lock, so its npm dependency resolution is not fully reproducible. Review the package manifest and resolved dependency tree before use. Put the absolute value of MCP_PATH in the configuration below. Never put mailbox keys in mcp.json.

Configuration

Config files are loaded from two locations (project overrides global per-server):

Location Scope
$ZOT_HOME/mcp.json Global ($XDG_STATE_HOME/zot/mcp.json when XDG_STATE_HOME is set)
.zot/mcp.json Project-level (in your project root)

Config Format

Standard MCP config — same as Claude Desktop, with zot-specific extensions:

{
  "mcpServers": {
    // ── Stdio transport (local subprocess) ───────────────────────────────────
    "filesystem": {
      "command": "npx",                    // executable to spawn
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
      "env": {                             // extra environment variables
        "NODE_ENV": "production"
      },
      "connectTimeout": 30,                // connection timeout (seconds)
      "requestTimeout": 60,                // per-request timeout (seconds)
      "idleTimeout": 300                   // idle timeout before stopping (seconds)
    },

    // Build Remote Agent (gbr/1). Pair with `gbr-agent pair`, then keep
    // `gbr-agent run` running. Use an absolute path to the pinned MCP checkout.
    "gbr": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/GrokBuildRemote-Agents/mcp/gbr-mcp/bin/gbr-mcp.js"]
    },

    // ── Streamable HTTP transport (modern HTTP) ─────────────────────────────
    "supabase": {
      "transport": "streamable-http",
      "url": "https://mcp.supabase.com/mcp",
      "headers": {                         // custom HTTP headers
        "Authorization": "Bearer YOUR_TOKEN"
      }
    },

    // ── SSE transport (legacy HTTP) ─────────────────────────────────────────
    "legacy-server": {
      "transport": "sse",
      "url": "https://example.com/sse"
    }
  }
}

Configuration Options

Field Type Default Description
command string — Executable to spawn (stdio only)
args string[] [] Arguments for the command
env object — Extra environment variables
transport string "stdio" Transport: "stdio", "streamable-http", or "sse"
url string — Server URL (HTTP transports only)
headers object — Custom HTTP headers (HTTP transports only)
connectTimeout number 30 Connection timeout in seconds
requestTimeout number 60 Per-request timeout in seconds
idleTimeout number 300 Idle timeout before stopping in seconds

Example: Multiple Servers

{
  "mcpServers": {
    // Filesystem access (stdio)
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
    },

    // Grep.app - Search GitHub (streamable-http)
    "grep": {
      "transport": "streamable-http",
      "url": "https://mcp.grep.app/"
    },

    // Database queries (stdio)
    "sqlite": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-sqlite", "test.db"]
    },

    // Documentation lookup (stdio)
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp@latest"]
    },

    // You.com web search (streamable-http, keyless)
    "you": {
      "transport": "streamable-http",
      "url": "https://api.you.com/mcp?profile=free"
    },

    // Serply Google-backed search (streamable-http, keyed)
    "serply": {
      "transport": "streamable-http",
      "url": "https://api.serply.io/mcp",
      "headers": {
        "X-Api-Key": "${SERPLY_API_KEY}"
      }
    }
  }
}

You.com template

/mcp setup add you registers the keyless You.com MCP profile (you-search). It needs no account or API key. To use the authenticated server and its additional tools, edit $ZOT_HOME/mcp.json after adding the template:

{
  "mcpServers": {
    "you": {
      "transport": "streamable-http",
      "url": "https://api.you.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_YDC_API_KEY"
      }
    }
  }
}

The authenticated endpoint does not expose you-finance by default. Request it explicitly with the ?tools= URL parameter or the X-Allowed-Tools header.

Serply template

/mcp setup add serply registers the Serply MCP server, which returns Google-backed results. It has no keyless profile, so the template is the first one that writes a headers entry:

{
  "mcpServers": {
    "serply": {
      "transport": "streamable-http",
      "url": "https://api.serply.io/mcp",
      "headers": {
        "X-Api-Key": "${SERPLY_API_KEY}"
      }
    }
  }
}

The template writes the variable reference, not the key, so this entry holds no secret. The file around it is a separate question: another server can hold a literal credential, the way the You.com example above writes one inline, so treat mcp.json as safe to commit or sync only when every entry in it uses a variable reference. The bridge expands the reference from its own environment at load time (see Environment variables); with SERPLY_API_KEY unset, this server is disabled and reported by name while every other server keeps working. Get a key at serply.io; the API reference is at serply.io/docs.

The server exposes 14 tools, so it covers several verticals rather than one general search:

tool returns
google_search Google organic results
google_news_search Google News
google_scholar_search Google Scholar, including citation counts
google_jobs_search Google Jobs
google_maps_search Google Maps places
google_video_search Google video results
bing_search Bing organic results
amazon_product_search Amazon product listings
scrape_url a URL's content through the proxy layer
reddit_subreddit_posts, reddit_subreddit_about, reddit_user_posts, reddit_post_comments, reddit_post Reddit subreddits, users, posts, and comments

They reach the model as mcp__serply__google_scholar_search and so on, per Tool Naming.

How It Works

┌──────────────────────────────────────────────────────────────┐
│  zot agent                                                    │
│                                                               │
│  ┌──────────┐    tool_call    ┌──────────────┐               │
│  │   LLM    │───────────────▶│  mcp-bridge  │               │
│  │          │◀───────────────│  (extension) │               │
│  └──────────┘    tool_result └──────┬───────┘               │
│                                      │                        │
│                           ┌──────────┼──────────┐            │
│                           ▼          ▼          ▼            │
│                    ┌──────────┐ ┌──────────┐ ┌──────────┐   │
│                    │   MCP    │ │   MCP    │ │   MCP    │   │
│                    │ server 1 │ │ server 2 │ │ server 3 │   │
│                    │ (stdio)  │ │ (stdio)  │ │ (stdio)  │   │
│                    └──────────┘ └──────────┘ └──────────┘   │
└──────────────────────────────────────────────────────────────┘
  1. Startup: mcp-bridge reads config and registers tools from mcp-tools-cache.json
  2. Background refresh: starts configured MCP servers, calls tools/list, and updates the cache when definitions change
  3. Reload: if the cache changed, run /reload-ext once so zot rebuilds the tool registry with the new definitions
  4. Naming: tools appear as mcp__<server>__<tool> (e.g., mcp__filesystem__read_file)
  5. Idle timeout: servers not used for 5 minutes are automatically stopped
  6. Auto-respawn: calling a tool on a stopped server wakes it up
  7. Routing: tool calls are forwarded to the appropriate MCP server

Slash Commands

Command Description
/mcp Show status of all configured servers
/mcp help Show available MCP commands
/mcp <name> Show detailed status for one server
/mcp start <name> Manually start a server
/mcp stop <name> Manually stop a server
/mcp restart Restart all servers
/mcp start all Manually start all servers
/mcp stop all Manually stop all servers
/mcp setup templates Show available setup templates
`/mcp setup add [--global --project] [--name ]`

Tool Naming

Tools are namespaced to avoid collisions with zot's built-in tools:

mcp__<server>__<tool>

Examples:

  • mcp__filesystem__read_file
  • mcp__filesystem__write_file
  • mcp__sqlite__query
  • mcp__context7__resolve-library-id

Server and tool names are sanitized (non-alphanumeric characters become _).

Smart Lazy Loading

The bridge uses a "smart lazy" strategy:

  1. On startup: cached tool definitions are registered without blocking zot startup
  2. In the background: servers start long enough to refresh the tool cache
  3. During use: servers stay running for fast tool calls
  4. After 5 min idle: unused servers are automatically stopped (saves memory/CPU)
  5. On next tool call: the server is respawned automatically (~1-3s delay)

This gives you:

  • Cached tools visible to the LLM immediately
  • Fast tool calls when actively working
  • Memory freed when not using MCP tools
  • One manual /reload-ext only when tool definitions change

Troubleshooting

Check server status:

/mcp

View extension logs:

zot ext logs mcp -f

Common issues:

  • Server fails to start: check that command exists in your PATH, or use absolute path
  • Tool not found: run /mcp to see if the server started successfully
  • Slow first call: server is respawning after idle timeout (normal)

Limitations

  • No OAuth flow — authentication requires manual token configuration in headers
  • No resources/prompts — only tools are bridged (MCP resources and prompts coming later)
  • No automatic config hot reload — run /reload-ext after setup/config changes

Development

# Build
cd examples/extensions/mcp-bridge
go build -o mcp-bridge .

# Test
go test ./...
go vet ./...

# Run without installing (for one zot session)
zot --ext .

# View logs
zot ext logs mcp -f

License

MIT

Testing

go test ./...
go vet ./...
go build -o /tmp/mcp-bridge .

Tested MCP servers:

Server Transport Result
@modelcontextprotocol/server-filesystem stdio 14 tools registered; file operations and MCP errors handled correctly
grep.app https://mcp.grep.app/ streamable-http searchGitHub registered and successfully searched public GitHub code

Note: grep.app uses the root endpoint /. Streamable HTTP protocol headers are handled automatically by the bridge and should not be written to mcp.json.

What the paired phone sees

Build Remote Agent exposes terminal windows on the machine. Its loopback :8788 endpoint is a Bot API that returns JSON, not an MCP endpoint or terminal transcript. See the third-party's current phone visibility documentation for details.

source
1# mcp-bridge
2
3Connect zot to [MCP (Model Context Protocol)](https://modelcontextprotocol.io) servers.
4
5This extension reads MCP server configurations from standard locations (same format as Claude Desktop, Cursor, Cline, etc.) and bridges their tools into zot so the LLM can call them directly.
6
7## Features
8
9- **Standard config format** — same JSON as Claude Desktop, Cursor, Cline
10- **On-demand tool discovery** — only `mcp__search_tools` is advertised initially; matching MCP schemas load when needed instead of bloating every model request
11- **Smart lazy loading** — cached definitions register as deferred tools at startup, servers wake for refresh or tool calls, then auto-sleep after idle time
12- **Auto-respawn** — calling a loaded tool on a sleeping server wakes it up automatically
13- **Multi-transport** — stdio, streamable-http, and SSE transports
14- **Multi-server** — connect to any number of MCP servers simultaneously
15- **Tool namespacing** — tools appear as `mcp__<server>__<tool>` to avoid collisions
16- **Tool annotations** — read-only, destructive, idempotent hints surfaced to LLM
17- **Configurable timeouts** — per-server connect, request, and idle timeouts
18- **Custom headers** — auth tokens and other headers for HTTP servers
19- **Slash commands** — `/mcp` to check status, start/stop/restart servers
20- **Better error messages** — context-aware errors with actionable suggestions
21
22## Environment variables
23
24Like [Claude Code](https://code.claude.com/docs/en/mcp#environment-variable-expansion-in-mcp-json), the bridge expands `${VAR}` and `${VAR:-default}` in `command`, `args`, `env` values, `url`, and `headers` values. This is client configuration compatibility, not a requirement of the MCP protocol.
25
26```json
27{"mcpServers":{"api":{"transport":"streamable-http","url":"${API_BASE_URL:-https://api.example.com}/mcp","headers":{"Authorization":"Bearer ${API_KEY}"}}}}
28```
29
30Expansion uses the bridge process environment after global/project configurations are merged. Defaults apply to unset variables; an explicitly empty variable stays empty. Values are expanded once, without shell execution, bare `$VAR` expansion, nested defaults, or references to sibling `env` entries. Config files are not rewritten. A missing variable without a default disables that server and reports the server, field, and variable name, never the field value; other valid servers remain available.
31
32If the project config cannot be read or parsed, the bridge reports that error and still expands and validates retained global servers. Servers with missing required variables are excluded in this case too.
33
34## Quick Start
35
361. **Build the extension:**
37
38   ```bash
39   cd examples/extensions/mcp-bridge
40   go build -o mcp-bridge .
41   ```
42
432. **Create a project config file:**
44
45   ```bash
46   mkdir -p .zot
47   cat > .zot/mcp.json << 'EOF'
48   {
49     "mcpServers": {
50       "filesystem": {
51         "command": "npx",
52         "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
53       },
54       "context7": {
55         "command": "npx",
56         "args": ["-y", "@upstash/context7-mcp@latest"]
57       }
58     }
59   }
60   EOF
61   ```
62
633. **Install the extension:**
64
65   ```bash
66   zot ext install .
67   ```
68
694. **Restart zot.** On first run the extension refreshes its tool cache in the background. When zot shows `MCP tool cache changed`, run `/reload-ext` once. Future launches register the cached MCP tools immediately as deferred definitions.
70
71The model initially sees one small loader tool, `mcp__search_tools`. It searches cached MCP tool names and descriptions locally, activates up to eight relevant definitions by default, and then calls the selected MCP tool normally. This keeps large MCP installations compatible with providers that limit request or tool-schema size.
72
73### Phone pairing with Build Remote Agent
74
75[Build Remote Agent](https://grokbuildremote.com/) is an optional, third-party integration that lets a paired phone observe terminal sessions and veto actions. It is an independent Linespotting AB product and is not affiliated with xAI or SpaceX.
76
77#### Install the agent
78
79Pin release `v0.6.0` and verify the binary against the checksum listed here. The release's own `SHA256SUMS` file does not currently match five of its six binary assets, so do not use that file as the trust source. These checksums were verified directly against the release assets on 2026-08-24:
80
81```text
8262673a6856342a87d4a2a659bc1de92200aa19a5b60d88d252254940820f0b7f  gbr-agent-darwin-amd64
837baa1a8e214cd71b60e3f2b5063713e00ff740939749c3cab3d702784a1432f8  gbr-agent-darwin-arm64
84fb54724367882497f2e8e05e40ecdeb4be29e008e6c865fc5c426cf464e6ad6e  gbr-agent-linux-amd64
859e9d7ca45bb0c4ded9d04226136013e9b64ae30f16bcf03069d35e9c38171cb9  gbr-agent-linux-arm64
8640355b2be6cd68f3be68f2a06dfd30307ec1a60f16f87f1d6174012b35aa4a49  gbr-agent-windows-amd64.exe
878fb9efcbc7e2ac91c11964944bf0f45e31bb23f4356d9dcb4b305d7cb9b0fe8c  gbr-agent-windows-arm64.exe
88```
89
90This macOS Apple Silicon example downloads, verifies, and installs the binary. Change both `ASSET` and `SHA` for another platform.
91
92```bash
93VER=v0.6.0
94ASSET=gbr-agent-darwin-arm64
95SHA=7baa1a8e214cd71b60e3f2b5063713e00ff740939749c3cab3d702784a1432f8
96BASE="https://github.com/LinespottingOrg/GrokBuildRemote-Agents/releases/download/$VER"
97curl -fsSL -o "$ASSET" "$BASE/$ASSET"
98if command -v sha256sum >/dev/null 2>&1; then
99  printf '%s  %s\n' "$SHA" "$ASSET" | sha256sum -c -
100else
101  printf '%s  %s\n' "$SHA" "$ASSET" | shasum -a 256 -c -
102fi
103mkdir -p "$HOME/.local/bin"
104install -m 0755 "$ASSET" "$HOME/.local/bin/gbr-agent"
105export PATH="$HOME/.local/bin:$PATH"
106gbr-agent version  # must report v0.6.0
107gbr-agent pair
108gbr-agent run
109```
110
111Keep `gbr-agent run` running. Its Bot API should only be available over loopback:
112
113```bash
114curl -sS http://127.0.0.1:8788/health
115curl -sS http://127.0.0.1:8788/v1/sessions
116```
117
118#### Install the MCP server
119
120The MCP server requires Node.js 20 or newer. Pin its source instead of cloning the mutable default branch:
121
122```bash
123git clone --branch v0.6.0 --depth 1 https://github.com/LinespottingOrg/GrokBuildRemote-Agents.git
124cd GrokBuildRemote-Agents/mcp/gbr-mcp
125npm install --ignore-scripts
126MCP_PATH="$(pwd)/bin/gbr-mcp.js"
127node "$MCP_PATH" --diagnose
128```
129
130The `v0.6.0` source does not include a package lock, so its npm dependency resolution is not fully reproducible. Review the package manifest and resolved dependency tree before use. Put the absolute value of `MCP_PATH` in the configuration below. Never put mailbox keys in `mcp.json`.
131
132## Configuration
133
134Config files are loaded from two locations (project overrides global per-server):
135
136| Location | Scope |
137|---|---|
138| `$ZOT_HOME/mcp.json` | Global (`$XDG_STATE_HOME/zot/mcp.json` when `XDG_STATE_HOME` is set) |
139| `.zot/mcp.json` | Project-level (in your project root) |
140
141### Config Format
142
143Standard MCP config — same as Claude Desktop, with zot-specific extensions:
144
145```jsonc
146{
147  "mcpServers": {
148    // ── Stdio transport (local subprocess) ───────────────────────────────────
149    "filesystem": {
150      "command": "npx",                    // executable to spawn
151      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
152      "env": {                             // extra environment variables
153        "NODE_ENV": "production"
154      },
155      "connectTimeout": 30,                // connection timeout (seconds)
156      "requestTimeout": 60,                // per-request timeout (seconds)
157      "idleTimeout": 300                   // idle timeout before stopping (seconds)
158    },
159
160    // Build Remote Agent (gbr/1). Pair with `gbr-agent pair`, then keep
161    // `gbr-agent run` running. Use an absolute path to the pinned MCP checkout.
162    "gbr": {
163      "command": "node",
164      "args": ["/ABSOLUTE/PATH/GrokBuildRemote-Agents/mcp/gbr-mcp/bin/gbr-mcp.js"]
165    },
166
167    // ── Streamable HTTP transport (modern HTTP) ─────────────────────────────
168    "supabase": {
169      "transport": "streamable-http",
170      "url": "https://mcp.supabase.com/mcp",
171      "headers": {                         // custom HTTP headers
172        "Authorization": "Bearer YOUR_TOKEN"
173      }
174    },
175
176    // ── SSE transport (legacy HTTP) ─────────────────────────────────────────
177    "legacy-server": {
178      "transport": "sse",
179      "url": "https://example.com/sse"
180    }
181  }
182}
183```
184
185### Configuration Options
186
187| Field | Type | Default | Description |
188|---|---|---|---|
189| `command` | string | — | Executable to spawn (stdio only) |
190| `args` | string[] | [] | Arguments for the command |
191| `env` | object | — | Extra environment variables |
192| `transport` | string | "stdio" | Transport: "stdio", "streamable-http", or "sse" |
193| `url` | string | — | Server URL (HTTP transports only) |
194| `headers` | object | — | Custom HTTP headers (HTTP transports only) |
195| `connectTimeout` | number | 30 | Connection timeout in seconds |
196| `requestTimeout` | number | 60 | Per-request timeout in seconds |
197| `idleTimeout` | number | 300 | Idle timeout before stopping in seconds |
198
199### Example: Multiple Servers
200
201```jsonc
202{
203  "mcpServers": {
204    // Filesystem access (stdio)
205    "filesystem": {
206      "command": "npx",
207      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
208    },
209
210    // Grep.app - Search GitHub (streamable-http)
211    "grep": {
212      "transport": "streamable-http",
213      "url": "https://mcp.grep.app/"
214    },
215
216    // Database queries (stdio)
217    "sqlite": {
218      "command": "npx",
219      "args": ["-y", "@modelcontextprotocol/server-sqlite", "test.db"]
220    },
221
222    // Documentation lookup (stdio)
223    "context7": {
224      "command": "npx",
225      "args": ["-y", "@upstash/context7-mcp@latest"]
226    },
227
228    // You.com web search (streamable-http, keyless)
229    "you": {
230      "transport": "streamable-http",
231      "url": "https://api.you.com/mcp?profile=free"
232    },
233
234    // Serply Google-backed search (streamable-http, keyed)
235    "serply": {
236      "transport": "streamable-http",
237      "url": "https://api.serply.io/mcp",
238      "headers": {
239        "X-Api-Key": "${SERPLY_API_KEY}"
240      }
241    }
242  }
243}
244```
245
246### You.com template
247
248`/mcp setup add you` registers the keyless You.com MCP profile
249(`you-search`). It needs no account or API key. To use the authenticated
250server and its additional tools, edit `$ZOT_HOME/mcp.json` after adding
251the template:
252
253```jsonc
254{
255  "mcpServers": {
256    "you": {
257      "transport": "streamable-http",
258      "url": "https://api.you.com/mcp",
259      "headers": {
260        "Authorization": "Bearer YOUR_YDC_API_KEY"
261      }
262    }
263  }
264}
265```
266
267The authenticated endpoint does not expose `you-finance` by default. Request
268it explicitly with the `?tools=` URL parameter or the `X-Allowed-Tools` header.
269
270### Serply template
271
272`/mcp setup add serply` registers the [Serply](https://serply.io) MCP server,
273which returns Google-backed results. It has no keyless profile, so the template
274is the first one that writes a `headers` entry:
275
276```jsonc
277{
278  "mcpServers": {
279    "serply": {
280      "transport": "streamable-http",
281      "url": "https://api.serply.io/mcp",
282      "headers": {
283        "X-Api-Key": "${SERPLY_API_KEY}"
284      }
285    }
286  }
287}
288```
289
290The template writes the variable reference, not the key, so this entry holds no
291secret. The file around it is a separate question: another server can hold a
292literal credential, the way the You.com example above writes one inline, so
293treat `mcp.json` as safe to commit or sync only when every entry in it uses a
294variable reference. The bridge expands the reference from its own environment
295at load time (see [Environment variables](#environment-variables));
296with `SERPLY_API_KEY` unset, this server is disabled and reported by name while
297every other server keeps working. Get a key at
298[serply.io](https://serply.io); the API reference is at
299[serply.io/docs](https://serply.io/docs).
300
301The server exposes 14 tools, so it covers several verticals rather than one
302general search:
303
304| tool | returns |
305|------|---------|
306| `google_search` | Google organic results |
307| `google_news_search` | Google News |
308| `google_scholar_search` | Google Scholar, including citation counts |
309| `google_jobs_search` | Google Jobs |
310| `google_maps_search` | Google Maps places |
311| `google_video_search` | Google video results |
312| `bing_search` | Bing organic results |
313| `amazon_product_search` | Amazon product listings |
314| `scrape_url` | a URL's content through the proxy layer |
315| `reddit_subreddit_posts`, `reddit_subreddit_about`, `reddit_user_posts`, `reddit_post_comments`, `reddit_post` | Reddit subreddits, users, posts, and comments |
316
317They reach the model as `mcp__serply__google_scholar_search` and so on, per
318[Tool Naming](#tool-naming).
319
320## How It Works
321
322```
323┌──────────────────────────────────────────────────────────────┐
324│  zot agent                                                    │
325│                                                               │
326│  ┌──────────┐    tool_call    ┌──────────────┐               │
327│  │   LLM    │───────────────▶│  mcp-bridge  │               │
328│  │          │◀───────────────│  (extension) │               │
329│  └──────────┘    tool_result └──────┬───────┘               │
330│                                      │                        │
331│                           ┌──────────┼──────────┐            │
332│                           ▼          ▼          ▼            │
333│                    ┌──────────┐ ┌──────────┐ ┌──────────┐   │
334│                    │   MCP    │ │   MCP    │ │   MCP    │   │
335│                    │ server 1 │ │ server 2 │ │ server 3 │   │
336│                    │ (stdio)  │ │ (stdio)  │ │ (stdio)  │   │
337│                    └──────────┘ └──────────┘ └──────────┘   │
338└──────────────────────────────────────────────────────────────┘
339```
340
3411. **Startup**: mcp-bridge reads config and registers tools from `mcp-tools-cache.json`
3422. **Background refresh**: starts configured MCP servers, calls `tools/list`, and updates the cache when definitions change
3433. **Reload**: if the cache changed, run `/reload-ext` once so zot rebuilds the tool registry with the new definitions
3444. **Naming**: tools appear as `mcp__<server>__<tool>` (e.g., `mcp__filesystem__read_file`)
3455. **Idle timeout**: servers not used for 5 minutes are automatically stopped
3466. **Auto-respawn**: calling a tool on a stopped server wakes it up
3477. **Routing**: tool calls are forwarded to the appropriate MCP server
348
349## Slash Commands
350
351| Command | Description |
352|---|---|
353| `/mcp` | Show status of all configured servers |
354| `/mcp help` | Show available MCP commands |
355| `/mcp <name>` | Show detailed status for one server |
356| `/mcp start <name>` | Manually start a server |
357| `/mcp stop <name>` | Manually stop a server |
358| `/mcp restart` | Restart all servers |
359| `/mcp start all` | Manually start all servers |
360| `/mcp stop all` | Manually stop all servers |
361| `/mcp setup templates` | Show available setup templates |
362| `/mcp setup add <template> [--global|--project] [--name <server-name>]` | Add a server from a template |
363
364## Tool Naming
365
366Tools are namespaced to avoid collisions with zot's built-in tools:
367
368```
369mcp__<server>__<tool>
370```
371
372Examples:
373- `mcp__filesystem__read_file`
374- `mcp__filesystem__write_file`
375- `mcp__sqlite__query`
376- `mcp__context7__resolve-library-id`
377
378Server and tool names are sanitized (non-alphanumeric characters become `_`).
379
380## Smart Lazy Loading
381
382The bridge uses a "smart lazy" strategy:
383
3841. **On startup**: cached tool definitions are registered without blocking zot startup
3852. **In the background**: servers start long enough to refresh the tool cache
3863. **During use**: servers stay running for fast tool calls
3874. **After 5 min idle**: unused servers are automatically stopped (saves memory/CPU)
3885. **On next tool call**: the server is respawned automatically (~1-3s delay)
389
390This gives you:
391- Cached tools visible to the LLM immediately
392- Fast tool calls when actively working
393- Memory freed when not using MCP tools
394- One manual `/reload-ext` only when tool definitions change
395
396## Troubleshooting
397
398**Check server status:**
399```
400/mcp
401```
402
403**View extension logs:**
404```bash
405zot ext logs mcp -f
406```
407
408**Common issues:**
409
410- **Server fails to start**: check that `command` exists in your PATH, or use absolute path
411- **Tool not found**: run `/mcp` to see if the server started successfully
412- **Slow first call**: server is respawning after idle timeout (normal)
413
414## Limitations
415
416- **No OAuth flow** — authentication requires manual token configuration in headers
417- **No resources/prompts** — only tools are bridged (MCP resources and prompts coming later)
418- **No automatic config hot reload** — run `/reload-ext` after setup/config changes
419
420## Development
421
422```bash
423# Build
424cd examples/extensions/mcp-bridge
425go build -o mcp-bridge .
426
427# Test
428go test ./...
429go vet ./...
430
431# Run without installing (for one zot session)
432zot --ext .
433
434# View logs
435zot ext logs mcp -f
436```
437
438## License
439
440MIT
441
442## Testing
443
444```bash
445go test ./...
446go vet ./...
447go build -o /tmp/mcp-bridge .
448```
449
450Tested MCP servers:
451
452| Server | Transport | Result |
453|---|---|---|
454| `@modelcontextprotocol/server-filesystem` | stdio | 14 tools registered; file operations and MCP errors handled correctly |
455| grep.app `https://mcp.grep.app/` | streamable-http | `searchGitHub` registered and successfully searched public GitHub code |
456
457Note: grep.app uses the root endpoint `/`. Streamable HTTP protocol headers are handled automatically by the bridge and should not be written to `mcp.json`.
458
459## What the paired phone sees
460
461Build Remote Agent exposes terminal windows on the machine. Its loopback `:8788` endpoint is a Bot API that returns JSON, not an MCP endpoint or terminal transcript. See the third-party's [current phone visibility documentation](https://github.com/LinespottingOrg/GrokBuildRemote-Agents/blob/main/docs/WHAT-THE-PHONE-SEES.md) for details.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close