OzBridge as an MCP server
OzBridge can expose its Oz CLI integration as a Model Context Protocol (MCP) server, so any MCP client — Claude Code, Cursor, Codex, etc. — can drive Warp Oz through the same tools that Copilot Chat sees inside VS Code.
Quick start
- Open VS Code settings (Ctrl+,).
- Enable the server:
ozBridge.mcpEnabled→true
- (optional) Change the port, bind address, or set a bearer token:
ozBridge.mcpPort(default3847)ozBridge.mcpBindAddress(default127.0.0.1— loopback only)ozBridge.mcpBearerToken(default empty = no auth)
- Watch the OzBridge output channel for the log line:
MCP server listening on http://127.0.0.1:3847/sse (6 tools)You can also start/stop the server on demand without touching settings:
OzBridge: Start MCP server(Command Palette)OzBridge: Stop MCP serverOzBridge: Show MCP server statusOzBridge: Copy MCP endpoint URLEndpoints
| Route | Method | Purpose | | — | — | — | |
/sse|GET| Opens a Server-Sent-Events stream. The first frame isevent: endpoint\ndata: /messages?sessionId=<uuid>— the client posts subsequent JSON-RPC requests there. | |/messages?sessionId=<uuid>|POST| Single JSON-RPC 2.0 request as the body. The server acknowledges with202 Acceptedand dispatches the response over the matching SSE stream. | |/health|GET| Returns{ ok, name, version, tools, sessions }. Unaffected by bearer auth only when token is unset. | All responses are JSON (Content-Type: application/json) except/ssewhich istext/event-stream.Protocol
OzBridge implements the Model Context Protocol 2025-03-26 (and gracefully negotiates down to 2024-11-05 on request). The supported method set is deliberately small:
initialize— returns server capabilities +serverInfo.ping— health probe, always returns{}.tools/list— enumerates the registered tools.tools/call— invokes a tool by name. Notifications (JSON-RPC requests without anid) are dropped if the method is unknown. Resource/prompt/sampling capabilities are not advertised in this release.Tools exposed
| Tool | Purpose | | — | — | |
oz_agent_run| Runoz agent runlocally with a prompt. Returns the full run payload. | |oz_agent_run_cloud| Launch a cloud run. Consumes Warp credits. | |oz_run_get| Fetch a run’s status and output by id. Read-only. | |oz_run_list| List recent runs; supportsall/active/completed/ raw status filters plus a numericlimit. | |oz_list_models| List the AI model ids available to the account (oz model list) and report the current default. Read-only. | |oz_set_default_model| Set the default Oz model for every OzBridge surface by writingdefaultModelinto the workspace.warp/warp-bridge.yaml. Validated againstoz model list. | The JSON schemas for theinputSchemaof each tool are emitted verbatim bytools/list, so clients can route arguments from their own prompts automatically.Bearer authentication
When
ozBridge.mcpBearerTokenis non-empty, every request must carry anAuthorization: Bearer <token>header. Requests missing or with a mismatching token receive401 Unauthorized. Comparison is constant-time viacrypto.timingSafeEqual. Bind to loopback (127.0.0.1) whenever possible; only changeozBridge.mcpBindAddressif you understand the implications.Integration examples
Claude Code
Add to
~/.claude.json:{ "mcpServers": { "oz-bridge": { "type": "sse", "url": "http://127.0.0.1:3847/sse", "headers": { "Authorization": "Bearer my-secret" } } } }Cursor
Add to
~/.cursor/mcp.json:{ "mcpServers": { "oz-bridge": { "url": "http://127.0.0.1:3847/sse", "headers": { "Authorization": "Bearer my-secret" } } } }Codex CLI
Add to
~/.codex/config.toml:[[mcp.servers]] name = "oz-bridge" url = "http://127.0.0.1:3847/sse" authorization = "Bearer my-secret"Raw protocol cheatsheet
# 1. Open the SSE stream (keep this process running). curl -N http://127.0.0.1:3847/sse # First frame printed: # event: endpoint # data: /messages?sessionId=<uuid> # 2. In another shell, list tools on the same sessionId. curl -X POST 'http://127.0.0.1:3847/messages?sessionId=<uuid>' \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' # 3. Invoke a tool. curl -X POST 'http://127.0.0.1:3847/messages?sessionId=<uuid>' \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc":"2.0", "id":2, "method":"tools/call", "params":{ "name":"oz_run_list", "arguments":{"status":"completed","limit":5} } }'Responses stream back on the SSE connection as:
event: message data: {"jsonrpc":"2.0","id":2,"result":{"filter":"completed","count":5,"items":[…]}}Troubleshooting
- Server fails to start with
EADDRINUSE— another process is bound toozBridge.mcpPort. Pick a different port or set it to0to let the OS choose an ephemeral one (you can retrieve the actual port via theOzBridge: Show MCP server statuscommand). - Client connects but gets
401— the bearer token on the client doesn’t matchozBridge.mcpBearerToken. Copy the token via the VS Code Settings UI, or clear it on both sides for local development. - No tools are returned — check the OzBridge output channel for
a log line like
MCP server listening on … (N tools). IfNis 0, the tool registry failed to populate; file a bug. - Connection drops after ~30 s — idle SSE streams are kept alive
with a
: keepalive\n\ncomment every 15 s. If your client still closes the stream, increase itskeep-alivetimeout.Security posture
- Binds to loopback by default; no traffic leaves the machine unless
you opt in via
ozBridge.mcpBindAddress. - Bearer token, when set, is required for every route — including
/health— so even reconnaissance probes are authenticated. - No prompt content or run output is persisted by the server; the bridge only forwards calls to the Oz CLI.
- The server exits cleanly on extension
deactivate()and idempotentOzBridge: Stop MCP servercalls, so there are no zombie listeners.Limitations in v0.6
resources,prompts,sampling,loggingMCP capabilities are not implemented.- No TLS termination. Put the server behind an authenticated reverse proxy if you need HTTPS.
- Auto-registration into the three major MCP clients (
~/.claude.jsonetc.) is manual in this release; a command to do it for you is planned for v0.6.x.