olace

[ daemon & cli ]

Olace Bridge

The Olace Bridge is an OpenAI-compatible endpoint served on your machine at http://127.0.0.1:5578/v1. Point any tool that speaks the OpenAI API at it, and that tool can use your whole Olace network: local models through Ollama, LM Studio and llama.cpp, plus the models on every paired host, reached over an end-to-end encrypted connection. Olace's servers never see the prompts or responses of local and paired requests.

This is how your other tools ride the network. The model id decides where inference happens, so a coding agent on your laptop can run on the big GPU at home just by naming it: ollama/qwen3.5:4b runs here, home-pc/ollama/qwen3.5:14b runs on your paired host.

Turn it on

In the app: Settings › Local AI › Olace Bridge. Or:

olace bridge on

It is off by default and listens on loopback only. Check it any time with olace bridge or curl http://127.0.0.1:5578/.

Model names

Models are provider-qualified, and paired hosts get a prefix from their pairing label:

ollama/qwen3.5:4b               local Ollama
lmstudio/google/gemma-4-e4b     local LM Studio
home-pc/ollama/qwen3.5:14b      paired host "Home PC"

Unambiguous shorthand is accepted; an ambiguous name returns a 404 with the candidates. GET /v1/models lists everything, including models on hosts that are currently offline.

Endpoints

RouteNotes
GET /v1/modelsUnified list across local and paired providers.
GET /v1/models/{id}Accepts canonical ids and unambiguous shorthand.
POST /v1/chat/completionsStreaming and non-streaming.
POST /v1/completionsLegacy text completions.
POST /v1/embeddingsLocal and paired models.

Examples

curl http://127.0.0.1:5578/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ollama/qwen3.5:4b",
    "messages": [{"role": "user", "content": "Hello from the Bridge"}]
  }'
from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:5578/v1", api_key="unused")
reply = client.chat.completions.create(
    model="home-pc/ollama/qwen3.5:14b",
    messages=[{"role": "user", "content": "Hello from the Bridge"}],
)
print(reply.choices[0].message.content)

Any OpenAI-compatible tool works the same way: set the base URL to http://127.0.0.1:5578/v1, set the API key to anything (or your Bridge key, below), and pick a model id from GET /v1/models.

Works with your tools

Most coding agents, editors, and chat apps accept a custom OpenAI-compatible endpoint. Where to point them:

ToolKindWhere to set it
ContinueCoding assistant (VS Code, JetBrains)~/.continue/config.yaml, apiBase
ClineCoding agent (VS Code)Settings › API Provider › OpenAI Compatible
ZedEditor with agent panelsettings.json, openai_compatible provider
OpenCodeTerminal coding agentopencode.json, provider baseURL
AiderTerminal pair programmerOPENAI_API_BASE + OPENAI_API_KEY env vars
Codex CLITerminal coding agent~/.codex/config.toml, base_url + wire_api = "chat"
Droid (Factory)Coding agent~/.factory/settings.json, customModels
Open WebUISelf-hosted chat UIAdmin Settings › Connections › OpenAI
JanDesktop chat appSettings › Model Providers › Add Provider
Chatbox, Cherry StudioDesktop chat appsAdd provider, type "OpenAI API Compatible"
Copilot for ObsidianNotes pluginCustom model, "3rd party (openai format)"

One worked example, Continue:

# ~/.continue/config.yaml
models:
  - name: Home GPU
    provider: openai
    model: home-pc/ollama/qwen3.5:14b
    apiBase: http://127.0.0.1:5578/v1

Practical notes that save a few minutes:

  • Most tools require a non-empty API key even when the Bridge has none set; any string works.
  • Tools with a "fetch models" button read GET /v1/models and will list your whole network, paired hosts included.
  • Browser and Electron-based tools (Obsidian plugins, web UIs) send an origin; add it to bridge_cors_origins in daemon.json to keep streaming working.
  • Open WebUI in Docker should use host.docker.internal instead of 127.0.0.1.
  • A few tools route model calls through their vendor's servers (Cursor's base-URL override, for example); those cannot reach an endpoint on your machine. The Bridge is local-first by design.

Authentication

By default there is no key and the Bridge accepts connections from this machine only. If you want a key anyway, or you plan to front the Bridge with a reverse proxy:

olace bridge key --require-key

The key is shown once and then required as Authorization: Bearer <key>. Rotate with --regenerate, remove with --no-key. Browser-based tools need their origin allowlisted in bridge_cors_origins (see Configuration).

Behavior worth knowing

  • Streaming. stream: true is supported. While a cold model loads, the stream sends keep-alive comment lines so clients do not time out.
  • Reasoning models stream their thinking as delta.reasoning_content. Send reasoning_effort: "none" to turn thinking off on models that allow it.
  • Images are accepted as base64 data URIs and downscaled on your device before sending; remote image URLs are rejected.
  • Honored parameters include tools, tool_choice, temperature, top_p, stop, max_tokens, response_format (JSON mode and JSON schema). Unsupported OpenAI extras are accepted and ignored; n > 1 and audio are rejected.
  • Paired hosts. Requests prefer a direct LAN connection and fall back to the encrypted relay when you are away. Sessions stay warm between requests, so bursts of agent calls skip the handshake. An offline host fails fast with 503 host_offline.
  • Errors use the standard OpenAI envelope, with meaningful codes like model_not_found, host_offline, host_busy, and context_length_exceeded.

A note on scope

The Bridge serves your local and paired models. Requests never route to Olace Cloud models, so a misconfigured tool can never quietly spend your credits.