feat(server): add --mdns-domain flag to customize mDNS hostname

Allow users to specify a custom domain name for mDNS service discovery
instead of the hardcoded 'opencode.local'. This enables running multiple
OpenCode instances on the same network with distinct mDNS names.

The option can be set via CLI flag (--mdns-domain) or config file
(server.mdnsDomain).

Closes #11794
This commit is contained in:
Luiz Guilherme D'Abruzzo Pereira
2026-02-02 11:19:54 -03:00
parent 3408f1a6ae
commit 22710ee202
5 changed files with 21 additions and 6 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ export const WebCommand = cmd({
UI.println( UI.println(
UI.Style.TEXT_INFO_BOLD + " mDNS: ", UI.Style.TEXT_INFO_BOLD + " mDNS: ",
UI.Style.TEXT_NORMAL, UI.Style.TEXT_NORMAL,
`opencode.local:${server.port}`, `${opts.mdnsDomain}:${server.port}`,
) )
} }
+8 -1
View File
@@ -17,6 +17,11 @@ const options = {
describe: "enable mDNS service discovery (defaults hostname to 0.0.0.0)", describe: "enable mDNS service discovery (defaults hostname to 0.0.0.0)",
default: false, default: false,
}, },
"mdns-domain": {
type: "string" as const,
describe: "custom domain name for mDNS service (default: opencode.local)",
default: "opencode.local",
},
cors: { cors: {
type: "string" as const, type: "string" as const,
array: true, array: true,
@@ -36,9 +41,11 @@ export async function resolveNetworkOptions(args: NetworkOptions) {
const portExplicitlySet = process.argv.includes("--port") const portExplicitlySet = process.argv.includes("--port")
const hostnameExplicitlySet = process.argv.includes("--hostname") const hostnameExplicitlySet = process.argv.includes("--hostname")
const mdnsExplicitlySet = process.argv.includes("--mdns") const mdnsExplicitlySet = process.argv.includes("--mdns")
const mdnsDomainExplicitlySet = process.argv.includes("--mdns-domain")
const corsExplicitlySet = process.argv.includes("--cors") const corsExplicitlySet = process.argv.includes("--cors")
const mdns = mdnsExplicitlySet ? args.mdns : (config?.server?.mdns ?? args.mdns) const mdns = mdnsExplicitlySet ? args.mdns : (config?.server?.mdns ?? args.mdns)
const mdnsDomain = mdnsDomainExplicitlySet ? args["mdns-domain"] : (config?.server?.mdnsDomain ?? args["mdns-domain"])
const port = portExplicitlySet ? args.port : (config?.server?.port ?? args.port) const port = portExplicitlySet ? args.port : (config?.server?.port ?? args.port)
const hostname = hostnameExplicitlySet const hostname = hostnameExplicitlySet
? args.hostname ? args.hostname
@@ -49,5 +56,5 @@ export async function resolveNetworkOptions(args: NetworkOptions) {
const argsCors = Array.isArray(args.cors) ? args.cors : args.cors ? [args.cors] : [] const argsCors = Array.isArray(args.cors) ? args.cors : args.cors ? [args.cors] : []
const cors = [...configCors, ...argsCors] const cors = [...configCors, ...argsCors]
return { hostname, port, mdns, cors } return { hostname, port, mdns, mdnsDomain, cors }
} }
+1
View File
@@ -860,6 +860,7 @@ export namespace Config {
port: z.number().int().positive().optional().describe("Port to listen on"), port: z.number().int().positive().optional().describe("Port to listen on"),
hostname: z.string().optional().describe("Hostname to listen on"), hostname: z.string().optional().describe("Hostname to listen on"),
mdns: z.boolean().optional().describe("Enable mDNS service discovery"), mdns: z.boolean().optional().describe("Enable mDNS service discovery"),
mdnsDomain: z.string().optional().describe("Custom domain name for mDNS service (default: opencode.local)"),
cors: z.array(z.string()).optional().describe("Additional domains to allow for CORS"), cors: z.array(z.string()).optional().describe("Additional domains to allow for CORS"),
}) })
.strict() .strict()
+3 -2
View File
@@ -7,17 +7,18 @@ export namespace MDNS {
let bonjour: Bonjour | undefined let bonjour: Bonjour | undefined
let currentPort: number | undefined let currentPort: number | undefined
export function publish(port: number) { export function publish(port: number, domain?: string) {
if (currentPort === port) return if (currentPort === port) return
if (bonjour) unpublish() if (bonjour) unpublish()
try { try {
const host = domain ?? "opencode.local"
const name = `opencode-${port}` const name = `opencode-${port}`
bonjour = new Bonjour() bonjour = new Bonjour()
const service = bonjour.publish({ const service = bonjour.publish({
name, name,
type: "http", type: "http",
host: "opencode.local", host,
port, port,
txt: { path: "/" }, txt: { path: "/" },
}) })
+8 -2
View File
@@ -563,7 +563,13 @@ export namespace Server {
return result return result
} }
export function listen(opts: { port: number; hostname: string; mdns?: boolean; cors?: string[] }) { export function listen(opts: {
port: number
hostname: string
mdns?: boolean
mdnsDomain?: string
cors?: string[]
}) {
_corsWhitelist = opts.cors ?? [] _corsWhitelist = opts.cors ?? []
const args = { const args = {
@@ -591,7 +597,7 @@ export namespace Server {
opts.hostname !== "localhost" && opts.hostname !== "localhost" &&
opts.hostname !== "::1" opts.hostname !== "::1"
if (shouldPublishMDNS) { if (shouldPublishMDNS) {
MDNS.publish(server.port!) MDNS.publish(server.port!, opts.mdnsDomain)
} else if (opts.mdns) { } else if (opts.mdns) {
log.warn("mDNS enabled but hostname is loopback; skipping mDNS publish") log.warn("mDNS enabled but hostname is loopback; skipping mDNS publish")
} }