v0.2.63 95e29d1

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
  • Smart lazy loading — cached tools register at startup, servers wake for refresh or tool calls, then auto-sleep after idle time
  • Auto-respawn — calling a 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

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.

Configuration

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

Location Scope
$ZOT_HOME/mcp.json Global (macOS: ~/Library/Application Support/zot/mcp.json)
.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)
    },

    // ── 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"]
    }
  }
}

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.

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- **Smart lazy loading** — cached tools register at startup, servers wake for refresh or tool calls, then auto-sleep after idle time
11- **Auto-respawn** — calling a tool on a sleeping server wakes it up automatically
12- **Multi-transport** — stdio, streamable-http, and SSE transports
13- **Multi-server** — connect to any number of MCP servers simultaneously
14- **Tool namespacing** — tools appear as `mcp__<server>__<tool>` to avoid collisions
15- **Tool annotations** — read-only, destructive, idempotent hints surfaced to LLM
16- **Configurable timeouts** — per-server connect, request, and idle timeouts
17- **Custom headers** — auth tokens and other headers for HTTP servers
18- **Slash commands** — `/mcp` to check status, start/stop/restart servers
19- **Better error messages** — context-aware errors with actionable suggestions
20
21## Quick Start
22
231. **Build the extension:**
24
25   ```bash
26   cd examples/extensions/mcp-bridge
27   go build -o mcp-bridge .
28   ```
29
302. **Create a project config file:**
31
32   ```bash
33   mkdir -p .zot
34   cat > .zot/mcp.json << 'EOF'
35   {
36     "mcpServers": {
37       "filesystem": {
38         "command": "npx",
39         "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
40       },
41       "context7": {
42         "command": "npx",
43         "args": ["-y", "@upstash/context7-mcp@latest"]
44       }
45     }
46   }
47   EOF
48   ```
49
503. **Install the extension:**
51
52   ```bash
53   zot ext install .
54   ```
55
564. **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.
57
58## Configuration
59
60Config files are loaded from two locations (project overrides global per-server):
61
62| Location | Scope |
63|---|---|
64| `$ZOT_HOME/mcp.json` | Global (macOS: `~/Library/Application Support/zot/mcp.json`) |
65| `.zot/mcp.json` | Project-level (in your project root) |
66
67### Config Format
68
69Standard MCP config — same as Claude Desktop, with zot-specific extensions:
70
71```jsonc
72{
73  "mcpServers": {
74    // ── Stdio transport (local subprocess) ───────────────────────────────────
75    "filesystem": {
76      "command": "npx",                    // executable to spawn
77      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
78      "env": {                             // extra environment variables
79        "NODE_ENV": "production"
80      },
81      "connectTimeout": 30,                // connection timeout (seconds)
82      "requestTimeout": 60,                // per-request timeout (seconds)
83      "idleTimeout": 300                   // idle timeout before stopping (seconds)
84    },
85
86    // ── Streamable HTTP transport (modern HTTP) ─────────────────────────────
87    "supabase": {
88      "transport": "streamable-http",
89      "url": "https://mcp.supabase.com/mcp",
90      "headers": {                         // custom HTTP headers
91        "Authorization": "Bearer YOUR_TOKEN"
92      }
93    },
94
95    // ── SSE transport (legacy HTTP) ─────────────────────────────────────────
96    "legacy-server": {
97      "transport": "sse",
98      "url": "https://example.com/sse"
99    }
100  }
101}
102```
103
104### Configuration Options
105
106| Field | Type | Default | Description |
107|---|---|---|---|
108| `command` | string | — | Executable to spawn (stdio only) |
109| `args` | string[] | [] | Arguments for the command |
110| `env` | object | — | Extra environment variables |
111| `transport` | string | "stdio" | Transport: "stdio", "streamable-http", or "sse" |
112| `url` | string | — | Server URL (HTTP transports only) |
113| `headers` | object | — | Custom HTTP headers (HTTP transports only) |
114| `connectTimeout` | number | 30 | Connection timeout in seconds |
115| `requestTimeout` | number | 60 | Per-request timeout in seconds |
116| `idleTimeout` | number | 300 | Idle timeout before stopping in seconds |
117
118### Example: Multiple Servers
119
120```jsonc
121{
122  "mcpServers": {
123    // Filesystem access (stdio)
124    "filesystem": {
125      "command": "npx",
126      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
127    },
128
129    // Grep.app - Search GitHub (streamable-http)
130    "grep": {
131      "transport": "streamable-http",
132      "url": "https://mcp.grep.app/"
133    },
134
135    // Database queries (stdio)
136    "sqlite": {
137      "command": "npx",
138      "args": ["-y", "@modelcontextprotocol/server-sqlite", "test.db"]
139    },
140
141    // Documentation lookup (stdio)
142    "context7": {
143      "command": "npx",
144      "args": ["-y", "@upstash/context7-mcp@latest"]
145    }
146  }
147}
148```
149
150## How It Works
151
152```
153┌──────────────────────────────────────────────────────────────┐
154│  zot agent                                                    │
155│                                                               │
156│  ┌──────────┐    tool_call    ┌──────────────┐               │
157│  │   LLM    │───────────────▶│  mcp-bridge  │               │
158│  │          │◀───────────────│  (extension) │               │
159│  └──────────┘    tool_result └──────┬───────┘               │
160│                                      │                        │
161│                           ┌──────────┼──────────┐            │
162│                           ▼          ▼          ▼            │
163│                    ┌──────────┐ ┌──────────┐ ┌──────────┐   │
164│                    │   MCP    │ │   MCP    │ │   MCP    │   │
165│                    │ server 1 │ │ server 2 │ │ server 3 │   │
166│                    │ (stdio)  │ │ (stdio)  │ │ (stdio)  │   │
167│                    └──────────┘ └──────────┘ └──────────┘   │
168└──────────────────────────────────────────────────────────────┘
169```
170
1711. **Startup**: mcp-bridge reads config and registers tools from `mcp-tools-cache.json`
1722. **Background refresh**: starts configured MCP servers, calls `tools/list`, and updates the cache when definitions change
1733. **Reload**: if the cache changed, run `/reload-ext` once so zot rebuilds the tool registry with the new definitions
1744. **Naming**: tools appear as `mcp__<server>__<tool>` (e.g., `mcp__filesystem__read_file`)
1755. **Idle timeout**: servers not used for 5 minutes are automatically stopped
1766. **Auto-respawn**: calling a tool on a stopped server wakes it up
1777. **Routing**: tool calls are forwarded to the appropriate MCP server
178
179## Slash Commands
180
181| Command | Description |
182|---|---|
183| `/mcp` | Show status of all configured servers |
184| `/mcp help` | Show available MCP commands |
185| `/mcp <name>` | Show detailed status for one server |
186| `/mcp start <name>` | Manually start a server |
187| `/mcp stop <name>` | Manually stop a server |
188| `/mcp restart` | Restart all servers |
189| `/mcp start all` | Manually start all servers |
190| `/mcp stop all` | Manually stop all servers |
191| `/mcp setup templates` | Show available setup templates |
192| `/mcp setup add <template> [--global|--project] [--name <server-name>]` | Add a server from a template |
193
194## Tool Naming
195
196Tools are namespaced to avoid collisions with zot's built-in tools:
197
198```
199mcp__<server>__<tool>
200```
201
202Examples:
203- `mcp__filesystem__read_file`
204- `mcp__filesystem__write_file`
205- `mcp__sqlite__query`
206- `mcp__context7__resolve-library-id`
207
208Server and tool names are sanitized (non-alphanumeric characters become `_`).
209
210## Smart Lazy Loading
211
212The bridge uses a "smart lazy" strategy:
213
2141. **On startup**: cached tool definitions are registered without blocking zot startup
2152. **In the background**: servers start long enough to refresh the tool cache
2163. **During use**: servers stay running for fast tool calls
2174. **After 5 min idle**: unused servers are automatically stopped (saves memory/CPU)
2185. **On next tool call**: the server is respawned automatically (~1-3s delay)
219
220This gives you:
221- Cached tools visible to the LLM immediately
222- Fast tool calls when actively working
223- Memory freed when not using MCP tools
224- One manual `/reload-ext` only when tool definitions change
225
226## Troubleshooting
227
228**Check server status:**
229```
230/mcp
231```
232
233**View extension logs:**
234```bash
235zot ext logs mcp -f
236```
237
238**Common issues:**
239
240- **Server fails to start**: check that `command` exists in your PATH, or use absolute path
241- **Tool not found**: run `/mcp` to see if the server started successfully
242- **Slow first call**: server is respawning after idle timeout (normal)
243
244## Limitations
245
246- **No OAuth flow** — authentication requires manual token configuration in headers
247- **No resources/prompts** — only tools are bridged (MCP resources and prompts coming later)
248- **No automatic config hot reload** — run `/reload-ext` after setup/config changes
249
250## Development
251
252```bash
253# Build
254cd examples/extensions/mcp-bridge
255go build -o mcp-bridge .
256
257# Test
258go test ./...
259go vet ./...
260
261# Run without installing (for one zot session)
262zot --ext .
263
264# View logs
265zot ext logs mcp -f
266```
267
268## License
269
270MIT
271
272## Testing
273
274```bash
275go test ./...
276go vet ./...
277go build -o /tmp/mcp-bridge .
278```
279
280Tested MCP servers:
281
282| Server | Transport | Result |
283|---|---|---|
284| `@modelcontextprotocol/server-filesystem` | stdio | 14 tools registered; file operations and MCP errors handled correctly |
285| grep.app `https://mcp.grep.app/` | streamable-http | `searchGitHub` registered and successfully searched public GitHub code |
286
287Note: grep.app uses the root endpoint `/`. Streamable HTTP protocol headers are handled automatically by the bridge and should not be written to `mcp.json`.
288

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