Repository navigation
Description
Is your feature request related to a problem?
When opencode talks to an LLM through a self-hosted gateway (LiteLLM, vLLM), that gateway often needs specific request headers — feature flags, routing hints, or tracing toggles such as Arize Phoenix's x-enable-phoenix-tracing. There is currently no way to set custom headers on opencode's outgoing LLM requests from this plugin.
The plugin already exposes a chat.headers-shaped surface conceptually (it owns the OTel integration), and @opencode-ai/plugin provides a chat.headers hook that fires for each outgoing LLM request. That hook is the natural, protocol-level place to add headers — no request interception or monkey-patching.
Describe the solution you'd like
Add a chat.headers hook with two settings:
OPENCODE_OUTBOUND_HEADERS— comma-separatedkey=valueheaders to inject (parsed by the existingparseAttributePairs).OPENCODE_OUTBOUND_ENDPOINTS— comma-separated endpoint URLs. When set, headers are injected only for requests whose resolved URL matches by hostname; when unset, headers go to every provider (backward compatible).
Endpoint scoping matters because chat.headers fires for every LLM request, including third-party providers (Anthropic, OpenAI). Without scoping, an unintended header — or worse, a credential someone puts in the env var — would be sent to all of them. The resolved URL mirrors opencode's own resolution: non-empty provider.options.baseURL if overridden, else model.api.url.
Both settings would also be available via the plugin-tuple options form (outboundHeaders, outboundEndpoints), following the established option > env > default precedence from #65.
Describe alternatives you've considered
- Global
fetchinterception to add headers — rejected for the same reasons raised in [Feature]: native MCP trace-context propagation (SEP-414) — stdio support, transport-agnostic #62: it is a process-wide workaround that carries transport concerns better handled at the hook layer. - Doing this in opencode core — the header need is deployment-specific (which gateway, which flags), so a plugin-level toggle is the right granularity.
Additional context
I have an implementation ready (handler extracted to src/handlers/chat-headers.ts, unit tests, README, all four checks passing) and will open a PR referencing this issue. This is scoped to custom headers only; W3C traceparent propagation is a natural follow-up but is a separate, opt-in concern (it would leak trace IDs to third parties by default), so I would like to keep it to a second PR.
One design question for you: endpoint matching is currently by hostname, which tolerates port/path differences. I am happy to switch to origin (scheme + host + port) if you prefer stricter matching.
Activity
dialupdisaster commentedon Jul 23, 2026
@waiyong will a combination of setting the pheonix header in the opencode config and this PR solve your issues?