v0.2.97 d25ea2b

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

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.

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)
    },

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

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