feat(serve): add CORS origins configuration support
Add --cors-origins flag to serve command allowing specification of allowed CORS origins for cross-origin requests. When no origins are specified, defaults to same-origin only for security.
Usage:
opencode serve --cors-origins "http://localhost:3000" "https://myapp.com"
opencode serve -c "http://localhost:3000"
Hey! I understand this might be considered a core feature, and I saw in the README that you don't accept PRs for those.
Feel free to close this if it doesn't align with the project's direction, totally okay! I built this because I was encountering CORS issues when tunneling the server, but I completely understand if this doesn't align with the vision.
Thanks for the amazing project!
I second this one. Really useful to have Opencode as a Backend service only.
Would be very useful. If you try to build a browser client you will not be able to make any requests without this feature.
fix conflicts and i'll merge - ty!
@braden-w Do you need some help with this?
Hey everyone! 👋
I fixed conflicts, but had some issues since the lazy wrapper around app didn't support args, and I want to start a discussion here.
After looking through the codebase, I'm not sure we need the lazy wrapper around app. The Server.app() function is only called in three places:
-
Server.listen()- called once when the server starts -
Server.openapi()- called once during OpenAPI spec generation (opencode generatecommand) - Plugin system - called once during plugin initialization
Each of these happens in completely different execution contexts and typically only once per command. So the expensive app creation (setting up ~30 routes, OpenAPI specs, middleware, etc.) only happens once anyway; the lazy caching isn't really providing any performance benefit.
For this PR, I ended up just removing the lazy wrapper entirely. That said, if we do want to keep lazy, there are a few options we could explore:
- Make
lazyaccept arguments - essentially turning it into a memoization function - Use a closure pattern: capture CORS config in the outer scope
- Parameterized cache: cache app instances by their configuration
But honestly, given the call patterns, I think the simplest solution (no caching) is probably the right one here.
What do you all think? Am I missing some use case where the app gets created multiple times in the same process?
Hey @thdxr , sorry for the ping, but just wanted to check in and get some feedback on the proposed changes. Is there a solution we could make so that app remains lazy while supporting CORS as parameters?
Would be very useful +1 for this.
It looks like CORS support has already been added to the main branch in a simpler way. The server now uses Hono's CORS middleware with permissive defaults:
packages/opencode/src/server/server.ts (line 125)
import { cors } from "hono/cors"
// ...
.use(cors())
This allows all origins by default, unlike this configurable origins approach. One less feature but simpler.
I think this PR can be closed since the feature is already implemented. Thank you @thdxr !