feat(opencode): add HTTP/HTTPS proxy support#10856
feat(opencode): add HTTP/HTTPS proxy support#10856Thesam1798 wants to merge 29 commits intoanomalyco:devfrom
Conversation
|
The following comment was made by an LLM, it may be inaccurate: Based on my search, I found one potentially related PR: PR #6025 - feat: add per-provider TLS and proxy configuration Why it's related: The searches for "proxyFetch", "NO_PROXY bypass", and specific fetch wrapper implementations only returned your current PR (10856), indicating this is likely a newer implementation approach. |
There was a problem hiding this comment.
Pull request overview
Adds proxy support for Bun-based networking by introducing a proxy-aware fetch wrapper that respects HTTP_PROXY / HTTPS_PROXY / NO_PROXY, plus documentation and tests.
Changes:
- Introduces
proxyFetch()and NO_PROXY pattern matching insrc/util/fetch.ts. - Adds
proxyconfiguration schema toopencode.jsonviaConfig.ProxyConfig. - Replaces many direct
fetch()calls withproxyFetch()and adds unit/integration tests + docs.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/opencode/src/util/fetch.ts | Adds proxy resolution (HTTP_PROXY/HTTPS_PROXY/NO_PROXY) and proxyFetch() wrapper. |
| packages/opencode/src/config/config.ts | Adds ProxyConfig zod schema and uses proxyFetch for remote config fetch. |
| packages/opencode/src/tool/websearch.ts | Routes Exa websearch requests through proxyFetch. |
| packages/opencode/src/tool/webfetch.ts | Routes web fetching requests through proxyFetch. |
| packages/opencode/src/tool/codesearch.ts | Routes Exa codesearch requests through proxyFetch. |
| packages/opencode/src/share/share.ts | Routes share API calls through proxyFetch. |
| packages/opencode/src/share/share-next.ts | Routes share-next API calls through proxyFetch. |
| packages/opencode/src/session/instruction.ts | Routes instruction URL fetches through proxyFetch. |
| packages/opencode/src/provider/provider.ts | Uses proxyFetch in provider fetch hook. |
| packages/opencode/src/provider/models.ts | Routes model snapshot fetch/refresh through proxyFetch. |
| packages/opencode/src/plugin/copilot.ts | Routes Copilot auth + token polling requests through proxyFetch. |
| packages/opencode/src/plugin/codex.ts | Routes Codex OAuth/token requests through proxyFetch. |
| packages/opencode/src/mcp/index.ts | Injects proxyFetch into MCP HTTP/SSE transports. |
| packages/opencode/src/lsp/server.ts | Routes LSP download and GitHub API calls through proxyFetch. |
| packages/opencode/src/installation/index.ts | Routes version check / registry queries through proxyFetch. |
| packages/opencode/src/file/ripgrep.ts | Routes ripgrep download through proxyFetch. |
| packages/opencode/src/cli/cmd/mcp.ts | Routes MCP debug connectivity request through proxyFetch. |
| packages/opencode/src/cli/cmd/import.ts | Routes share import request through proxyFetch. |
| packages/opencode/src/cli/cmd/github.ts | Routes GitHub integration HTTP calls through proxyFetch. |
| packages/opencode/src/cli/cmd/auth.ts | Routes .well-known/opencode fetch through proxyFetch. |
| packages/opencode/test/util/fetch.test.ts | Adds unit tests for proxy config parsing and NO_PROXY matching. |
| packages/opencode/test/util/fetch-integration.test.ts | Adds opt-in integration tests (skipped in CI) for proxy behavior. |
| packages/opencode/docs/proxy.md | Documents proxy env vars, config file format, NO_PROXY patterns, and troubleshooting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d09d16e to
775ed63
Compare
|
This PR (#10856) implements:
PR #6025 focuses on:
The two PRs are complementary - this one provides the global proxy infrastructure, while #6025 will add provider-specific overrides on top of it. |
49a10d7 to
45b3b85
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Real-world feedbackI encountered this issue with a corporate proxy. Without this fix, opencode was completely unusable:
After this fix, opencode works perfectly without any special configuration - the While waiting for reviews on this PR, I'm using a locally built version and everything works as expected! |
062927c to
3f81638
Compare
00637c0 to
71e0ba2
Compare
f1ae801 to
08fa7f7
Compare
2823a00 to
e121b7d
Compare
|
Thanks for this PR! I’m a Desktop user behind a corporate proxy and can’t reliably inject env vars into GUI apps. A config-file proxy (opencode.json) would solve this for me. This is blocking adoption on my side—any chance to merge soon? |
Add Zod schema for proxy configuration with: - http: HTTP proxy URL - https: HTTPS proxy URL - no_proxy: Array of hosts/patterns to bypass Uses .string() instead of .string().url() for flexibility (supports formats like proxy:8080 without schema). Part of proxy support feature to work around Bun's fetch() ignoring HTTP_PROXY/HTTPS_PROXY environment variables.
Create proxyFetch wrapper that explicitly passes proxy to Bun's fetch() since Bun ignores HTTP_PROXY/HTTPS_PROXY environment variables. Exports: - proxyFetch(input, init) - Main fetch wrapper - getProxyConfig() - Read config/env proxy settings - shouldBypassProxy(hostname, noProxy) - Check NO_PROXY patterns - getProxyForUrl(url) - Resolve proxy for a URL - setProxyConfig(config) - Init from opencode.json config Features: - Config file takes precedence over environment variables - Supports NO_PROXY patterns: *, hostname, *.domain, .domain - Feature flag OPENCODE_DISABLE_PROXY to bypass proxy - Per-request proxy override or disable via init.proxy This is the SPOF (single point of failure) for all proxy support.
Replace native fetch() with proxyFetch() in: - webfetch.ts: Web page fetching tool (2 calls) - websearch.ts: Exa MCP search API (1 call) - codesearch.ts: Exa MCP code search API (1 call)
Replace native fetch() with proxyFetch() in: - share.ts: sync, create, remove (3 calls) - share-next.ts: create, sync, remove (3 calls) These fetch calls communicate with OpenCode sharing API.
Pass proxyFetch to MCP SDK transports via the 'fetch' option: - StreamableHTTPClientTransport (2 instances) - SSEClientTransport (1 instance) The MCP SDK uses internal fetch calls for HTTP communication. By passing our proxyFetch wrapper, remote MCP servers become accessible through corporate proxies. This is critical for users connecting to remote MCP servers like mcp.exa.ai from behind a proxy.
Add proxyFetch import and replace fetch for ESLint server download. This enables ESLint VSCode extension download through corporate proxies.
Replace fetch with proxyFetch for: - ZLS (Zig Language Server): release info + binary download - Clangd (C/C++): release info + binary download These servers download binaries from GitHub releases.
Replace fetch with proxyFetch for: - Elixir-LS: source download - Kotlin LSP: release info - Lua Language Server: release info + binary download - Terraform-LS: release info + binary download - TexLab: release info + binary download - Tinymist: release info + binary download All these servers download binaries from GitHub.
Replace fetch with proxyFetch for ripgrep binary download. This is critical as ripgrep is used for file searching/grep operations.
Replace fetch with proxyFetch for .well-known/opencode endpoint. This enables enterprise config discovery through proxies.
Replace fetch with proxyFetch for remote instruction URLs. This enables loading instructions from remote URLs through proxies.
Replace fetch with proxyFetch in: - copilot.ts: API calls, device code flow, access token flow - codex.ts: Token exchange, token refresh, API calls These plugins use OAuth flows that require external API access.
Replace fetch() with proxyFetch() in CLI command files: - auth.ts: Provider authentication well-known endpoint - import.ts: Session import from opncd.ai URLs - mcp.ts: MCP server list refresh from models.opencode.ai - github.ts: GitHub API calls for Copilot auth and token exchange
Add integration tests that: - Test actual proxy requests (skipped in CI) - Verify NO_PROXY bypass patterns - Test OPENCODE_DISABLE_PROXY flag - Test config override of environment variables Tests require HTTPS_PROXY to be set to run real proxy tests.
Add comprehensive documentation for HTTP/HTTPS proxy support: - Environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY) - Configuration file options (opencode.json proxy section) - NO_PROXY pattern syntax and examples - Troubleshooting guide - Example configurations for common scenarios
- Add tls.rejectUnauthorized and tls.ca options to ProxyConfig schema - Implement getTlsForProxy() with path traversal validation - Wire TLS config into proxyFetch() when proxy is used - Add security warning when certificate validation is disabled Closes #10227
- Test getTlsForProxy() returns undefined when no TLS config - Test rejectUnauthorized option (true/false) - Test CA certificate path handling (single/multiple) - Test path traversal validation throws error
- Add TLS section explaining CA certificate configuration - Document single and multiple CA certificate paths - Document rejectUnauthorized option with security warning - Add reference from SSL/TLS troubleshooting section
e121b7d to
292afe5
Compare
|
I'll check this week, but I think the latest versions of Bun and Opencode fix this! If so, I'll close this PR, otherwise I'll continue to update it from my Dev branch. |
|
I tested the native 1.2.6 version, and the issue has been resolved. |
Fixes #10227
Related: #9736, #8822
Summary
Bun's native
fetch()ignoresHTTP_PROXY/HTTPS_PROXYenvironment variables. This PR adds aproxyFetchwrapper that reads proxy configuration and passes it to Bun's fetch.Changes
ProxyConfigschema in config.tsproxyFetchwrapper insrc/util/fetch.tsfetch()calls withproxyFetch()across ~20 filesNO_PROXYpatterns (wildcards, suffixes)OPENCODE_DISABLE_PROXYemergency bypass flagdocs/proxy.mdConfiguration
Environment variables:
Or in
opencode.json:{ "proxy": { "https": "http://proxy:8080", "no_proxy": ["localhost", "*.internal.com"] } }Verification
NO_PROXYbypass works for internal hosts