Browse Source

Revert "feat(core): optional mdns service (#6192)"

This reverts commit 26e7043718fbf5fbf08eecd04ff8ed5edd82e33e.
Aiden Cline 3 months ago
parent
commit
505068d5a6

+ 0 - 11
bun.lock

@@ -292,7 +292,6 @@
         "@standard-schema/spec": "1.0.0",
         "@zip.js/zip.js": "2.7.62",
         "ai": "catalog:",
-        "bonjour-service": "1.3.0",
         "bun-pty": "0.4.2",
         "chokidar": "4.0.3",
         "clipboardy": "4.0.0",
@@ -1082,8 +1081,6 @@
 
     "@kurkle/color": ["@kurkle/[email protected]", "", {}, "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="],
 
-    "@leichtgewicht/ip-codec": ["@leichtgewicht/[email protected]", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="],
-
     "@mdx-js/mdx": ["@mdx-js/[email protected]", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="],
 
     "@mixmark-io/domino": ["@mixmark-io/[email protected]", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="],
@@ -2006,8 +2003,6 @@
 
     "body-parser": ["[email protected]", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g=="],
 
-    "bonjour-service": ["[email protected]", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA=="],
-
     "boolbase": ["[email protected]", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
 
     "bottleneck": ["[email protected]", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="],
@@ -2252,8 +2247,6 @@
 
     "dlv": ["[email protected]", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
 
-    "dns-packet": ["[email protected]", "", { "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" } }, "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw=="],
-
     "dom-serializer": ["[email protected]", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
 
     "domelementtype": ["[email protected]", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
@@ -3030,8 +3023,6 @@
 
     "ms": ["[email protected]", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
 
-    "multicast-dns": ["[email protected]", "", { "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" }, "bin": { "multicast-dns": "cli.js" } }, "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg=="],
-
     "mustache": ["[email protected]", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
 
     "mysql2": ["[email protected]", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-Cs/jx3WZPNrYHVz+Iunp9ziahaG5uFMvD2R8Zlmc194AqXNxt9HBNu7ZsPYrUtmJsF0egETCWIdMIYAwOGjL1w=="],
@@ -3604,8 +3595,6 @@
 
     "three": ["[email protected]", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="],
 
-    "thunky": ["[email protected]", "", {}, "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="],
-
     "tiny-inflate": ["[email protected]", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
 
     "tiny-invariant": ["[email protected]", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],

+ 3 - 3
flake.lock

@@ -2,11 +2,11 @@
   "nodes": {
     "nixpkgs": {
       "locked": {
-        "lastModified": 1766747458,
-        "narHash": "sha256-m63jjuo/ygo8ztkCziYh5OOIbTSXUDkKbqw3Vuqu4a4=",
+        "lastModified": 1766532406,
+        "narHash": "sha256-acLU/ag9VEoKkzOD202QASX25nG1eArXg5A0mHjKgxM=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "c633f572eded8c4f3c75b8010129854ed404a6ce",
+        "rev": "8142186f001295e5a3239f485c8a49bf2de2695a",
         "type": "github"
       },
       "original": {

+ 0 - 1
packages/opencode/package.json

@@ -88,7 +88,6 @@
     "@standard-schema/spec": "1.0.0",
     "@zip.js/zip.js": "2.7.62",
     "ai": "catalog:",
-    "bonjour-service": "1.3.0",
     "bun-pty": "0.4.2",
     "chokidar": "4.0.3",
     "clipboardy": "4.0.0",

+ 20 - 10
packages/opencode/src/cli/cmd/acp.ts

@@ -3,10 +3,8 @@ import { bootstrap } from "../bootstrap"
 import { cmd } from "./cmd"
 import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
 import { ACP } from "@/acp/agent"
-import { Config } from "@/config/config"
 import { Server } from "@/server/server"
 import { createOpencodeClient } from "@opencode-ai/sdk/v2"
-import { withNetworkOptions, resolveNetworkOptions } from "../network"
 
 const log = Log.create({ service: "acp-command" })
 
@@ -21,17 +19,29 @@ export const AcpCommand = cmd({
   command: "acp",
   describe: "start ACP (Agent Client Protocol) server",
   builder: (yargs) => {
-    return withNetworkOptions(yargs).option("cwd", {
-      describe: "working directory",
-      type: "string",
-      default: process.cwd(),
-    })
+    return yargs
+      .option("cwd", {
+        describe: "working directory",
+        type: "string",
+        default: process.cwd(),
+      })
+      .option("port", {
+        type: "number",
+        describe: "port to listen on",
+        default: 0,
+      })
+      .option("hostname", {
+        type: "string",
+        describe: "hostname to listen on",
+        default: "127.0.0.1",
+      })
   },
   handler: async (args) => {
     await bootstrap(process.cwd(), async () => {
-      const config = await Config.get()
-      const opts = resolveNetworkOptions(args, config)
-      const server = Server.listen(opts)
+      const server = Server.listen({
+        port: args.port,
+        hostname: args.hostname,
+      })
 
       const sdk = createOpencodeClient({
         baseUrl: `http://${server.hostname}:${server.port}`,

+ 19 - 6
packages/opencode/src/cli/cmd/serve.ts

@@ -1,16 +1,29 @@
-import { Config } from "../../config/config"
 import { Server } from "../../server/server"
 import { cmd } from "./cmd"
-import { withNetworkOptions, resolveNetworkOptions } from "../network"
 
 export const ServeCommand = cmd({
   command: "serve",
-  builder: (yargs) => withNetworkOptions(yargs),
+  builder: (yargs) =>
+    yargs
+      .option("port", {
+        alias: ["p"],
+        type: "number",
+        describe: "port to listen on",
+        default: 0,
+      })
+      .option("hostname", {
+        type: "string",
+        describe: "hostname to listen on",
+        default: "127.0.0.1",
+      }),
   describe: "starts a headless opencode server",
   handler: async (args) => {
-    const config = await Config.get()
-    const opts = resolveNetworkOptions(args, config)
-    const server = Server.listen(opts)
+    const hostname = args.hostname
+    const port = args.port
+    const server = Server.listen({
+      port,
+      hostname,
+    })
     console.log(`opencode server listening on http://${server.hostname}:${server.port}`)
     await new Promise(() => {})
     await server.stop()

+ 19 - 9
packages/opencode/src/cli/cmd/tui/spawn.ts

@@ -1,23 +1,33 @@
 import { cmd } from "@/cli/cmd/cmd"
-import { Config } from "@/config/config"
 import { Instance } from "@/project/instance"
 import path from "path"
 import { Server } from "@/server/server"
 import { upgrade } from "@/cli/upgrade"
-import { withNetworkOptions, resolveNetworkOptions } from "@/cli/network"
 
 export const TuiSpawnCommand = cmd({
   command: "spawn [project]",
   builder: (yargs) =>
-    withNetworkOptions(yargs).positional("project", {
-      type: "string",
-      describe: "path to start opencode in",
-    }),
+    yargs
+      .positional("project", {
+        type: "string",
+        describe: "path to start opencode in",
+      })
+      .option("port", {
+        type: "number",
+        describe: "port to listen on",
+        default: 0,
+      })
+      .option("hostname", {
+        type: "string",
+        describe: "hostname to listen on",
+        default: "127.0.0.1",
+      }),
   handler: async (args) => {
     upgrade()
-    const config = await Config.get()
-    const opts = resolveNetworkOptions(args, config)
-    const server = Server.listen(opts)
+    const server = Server.listen({
+      port: args.port,
+      hostname: "127.0.0.1",
+    })
     const bin = process.execPath
     const cmd = []
     let cwd = process.cwd()

+ 16 - 6
packages/opencode/src/cli/cmd/tui/thread.ts

@@ -6,8 +6,6 @@ import path from "path"
 import { UI } from "@/cli/ui"
 import { iife } from "@/util/iife"
 import { Log } from "@/util/log"
-import { withNetworkOptions, resolveNetworkOptions } from "@/cli/network"
-import { Config } from "@/config/config"
 
 declare global {
   const OPENCODE_WORKER_PATH: string
@@ -17,7 +15,7 @@ export const TuiThreadCommand = cmd({
   command: "$0 [project]",
   describe: "start opencode tui",
   builder: (yargs) =>
-    withNetworkOptions(yargs)
+    yargs
       .positional("project", {
         type: "string",
         describe: "path to start opencode in",
@@ -38,12 +36,23 @@ export const TuiThreadCommand = cmd({
         describe: "session id to continue",
       })
       .option("prompt", {
+        alias: ["p"],
         type: "string",
         describe: "prompt to use",
       })
       .option("agent", {
         type: "string",
         describe: "agent to use",
+      })
+      .option("port", {
+        type: "number",
+        describe: "port to listen on",
+        default: 0,
+      })
+      .option("hostname", {
+        type: "string",
+        describe: "hostname to listen on",
+        default: "127.0.0.1",
       }),
   handler: async (args) => {
     // Resolve relative paths against PWD to preserve behavior when using --cwd flag
@@ -78,9 +87,10 @@ export const TuiThreadCommand = cmd({
     process.on("unhandledRejection", (e) => {
       Log.Default.error(e)
     })
-    const config = await Config.get()
-    const networkOpts = resolveNetworkOptions(args, config)
-    const server = await client.call("server", networkOpts)
+    const server = await client.call("server", {
+      port: args.port,
+      hostname: args.hostname,
+    })
     const prompt = await iife(async () => {
       const piped = !process.stdin.isTTY ? await Bun.stdin.text() : undefined
       if (!args.prompt) return piped

+ 1 - 1
packages/opencode/src/cli/cmd/tui/worker.ts

@@ -30,7 +30,7 @@ process.on("uncaughtException", (e) => {
 
 let server: Bun.Server<BunWebSocketData>
 export const rpc = {
-  async server(input: { port: number; hostname: string; mdns?: boolean }) {
+  async server(input: { port: number; hostname: string }) {
     if (server) await server.stop(true)
     try {
       server = Server.listen(input)

+ 20 - 11
packages/opencode/src/cli/cmd/web.ts

@@ -1,8 +1,6 @@
-import { Config } from "../../config/config"
 import { Server } from "../../server/server"
 import { UI } from "../ui"
 import { cmd } from "./cmd"
-import { withNetworkOptions, resolveNetworkOptions } from "../network"
 import open from "open"
 import { networkInterfaces } from "os"
 
@@ -30,17 +28,32 @@ function getNetworkIPs() {
 
 export const WebCommand = cmd({
   command: "web",
-  builder: (yargs) => withNetworkOptions(yargs),
+  builder: (yargs) =>
+    yargs
+      .option("port", {
+        alias: ["p"],
+        type: "number",
+        describe: "port to listen on",
+        default: 0,
+      })
+      .option("hostname", {
+        type: "string",
+        describe: "hostname to listen on",
+        default: "127.0.0.1",
+      }),
   describe: "starts a headless opencode server",
   handler: async (args) => {
-    const config = await Config.get()
-    const opts = resolveNetworkOptions(args, config)
-    const server = Server.listen(opts)
+    const hostname = args.hostname
+    const port = args.port
+    const server = Server.listen({
+      port,
+      hostname,
+    })
     UI.empty()
     UI.println(UI.logo("  "))
     UI.empty()
 
-    if (opts.hostname === "0.0.0.0") {
+    if (hostname === "0.0.0.0") {
       // Show localhost for local access
       const localhostUrl = `http://localhost:${server.port}`
       UI.println(UI.Style.TEXT_INFO_BOLD + "  Local access:      ", UI.Style.TEXT_NORMAL, localhostUrl)
@@ -57,10 +70,6 @@ export const WebCommand = cmd({
         }
       }
 
-      if (opts.mdns) {
-        UI.println(UI.Style.TEXT_INFO_BOLD + "  mDNS:              ", UI.Style.TEXT_NORMAL, "opencode.local")
-      }
-
       // Open localhost in browser
       open(localhostUrl.toString()).catch(() => {})
     } else {

+ 0 - 42
packages/opencode/src/cli/network.ts

@@ -1,42 +0,0 @@
-import type { Argv, InferredOptionTypes } from "yargs"
-import type { Config } from "../config/config"
-
-const options = {
-  port: {
-    type: "number" as const,
-    describe: "port to listen on",
-    default: 0,
-  },
-  hostname: {
-    type: "string" as const,
-    describe: "hostname to listen on",
-    default: "127.0.0.1",
-  },
-  mdns: {
-    type: "boolean" as const,
-    describe: "enable mDNS service discovery (defaults hostname to 0.0.0.0)",
-    default: false,
-  },
-}
-
-export type NetworkOptions = InferredOptionTypes<typeof options>
-
-export function withNetworkOptions<T>(yargs: Argv<T>) {
-  return yargs.options(options)
-}
-
-export function resolveNetworkOptions(args: NetworkOptions, config?: Config.Info) {
-  const portExplicitlySet = process.argv.includes("--port")
-  const hostnameExplicitlySet = process.argv.includes("--hostname")
-  const mdnsExplicitlySet = process.argv.includes("--mdns")
-
-  const mdns = mdnsExplicitlySet ? args.mdns : (config?.server?.mdns ?? args.mdns)
-  const port = portExplicitlySet ? args.port : (config?.server?.port ?? args.port)
-  const hostname = hostnameExplicitlySet
-    ? args.hostname
-    : mdns && !config?.server?.hostname
-      ? "0.0.0.0"
-      : (config?.server?.hostname ?? args.hostname)
-
-  return { hostname, port, mdns }
-}

+ 0 - 12
packages/opencode/src/config/config.ts

@@ -587,17 +587,6 @@ export namespace Config {
       .describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"),
   })
 
-  export const Server = z
-    .object({
-      port: z.number().int().positive().optional().describe("Port to listen on"),
-      hostname: z.string().optional().describe("Hostname to listen on"),
-      mdns: z.boolean().optional().describe("Enable mDNS service discovery"),
-    })
-    .strict()
-    .meta({
-      ref: "ServerConfig",
-    })
-
   export const Layout = z.enum(["auto", "stretch"]).meta({
     ref: "LayoutConfig",
   })
@@ -646,7 +635,6 @@ export namespace Config {
       keybinds: Keybinds.optional().describe("Custom keybind configurations"),
       logLevel: Log.Level.optional().describe("Log level"),
       tui: TUI.optional().describe("TUI specific settings"),
-      server: Server.optional().describe("Server configuration for opencode serve and web commands"),
       command: z
         .record(z.string(), Command)
         .optional()

+ 0 - 57
packages/opencode/src/server/mdns.ts

@@ -1,57 +0,0 @@
-import { Log } from "@/util/log"
-import Bonjour from "bonjour-service"
-
-const log = Log.create({ service: "mdns" })
-
-export namespace MDNS {
-  let bonjour: Bonjour | undefined
-  let currentPort: number | undefined
-
-  export function publish(port: number, name = "opencode") {
-    if (currentPort === port) return
-    if (bonjour) unpublish()
-
-    try {
-      bonjour = new Bonjour()
-      const service = bonjour.publish({
-        name,
-        type: "http",
-        port,
-        txt: { path: "/" },
-      })
-
-      service.on("up", () => {
-        log.info("mDNS service published", { name, port })
-      })
-
-      service.on("error", (err) => {
-        log.error("mDNS service error", { error: err })
-      })
-
-      currentPort = port
-    } catch (err) {
-      log.error("mDNS publish failed", { error: err })
-      if (bonjour) {
-        try {
-          bonjour.destroy()
-        } catch {}
-      }
-      bonjour = undefined
-      currentPort = undefined
-    }
-  }
-
-  export function unpublish() {
-    if (bonjour) {
-      try {
-        bonjour.unpublishAll()
-        bonjour.destroy()
-      } catch (err) {
-        log.error("mDNS unpublish failed", { error: err })
-      }
-      bonjour = undefined
-      currentPort = undefined
-      log.info("mDNS service unpublished")
-    }
-  }
-}

+ 5 - 28
packages/opencode/src/server/server.ts

@@ -45,11 +45,9 @@ import { Snapshot } from "@/snapshot"
 import { SessionSummary } from "@/session/summary"
 import { SessionStatus } from "@/session/status"
 import { upgradeWebSocket, websocket } from "hono/bun"
-import type { BunWebSocketData } from "hono/bun"
 import { errors } from "./error"
 import { Pty } from "@/pty"
 import { Installation } from "@/installation"
-import { MDNS } from "./mdns"
 
 // @ts-ignore This global is needed to prevent ai-sdk from logging warnings to stdout https://github.com/vercel/ai/blob/2dc67e0ef538307f21368db32d5a12345d98831b/packages/ai/src/logger/log-warnings.ts#L85
 globalThis.AI_SDK_LOG_WARNINGS = false
@@ -2625,41 +2623,20 @@ export namespace Server {
     return result
   }
 
-  export function listen(opts: { port: number; hostname: string; mdns?: boolean }) {
+  export function listen(opts: { port: number; hostname: string }) {
     const args = {
       hostname: opts.hostname,
       idleTimeout: 0,
       fetch: App().fetch,
       websocket: websocket,
     } as const
-    const tryServe = (port: number) => {
+    if (opts.port === 0) {
       try {
-        return Bun.serve({ ...args, port })
+        return Bun.serve({ ...args, port: 4096 })
       } catch {
-        return undefined
+        // port 4096 not available, fall through to use port 0
       }
     }
-    const server = opts.port === 0 ? (tryServe(4096) ?? tryServe(0)) : tryServe(opts.port)
-    if (!server) throw new Error(`Failed to start server on port ${opts.port}`)
-
-    const shouldPublishMDNS =
-      opts.mdns &&
-      server.port &&
-      opts.hostname !== "127.0.0.1" &&
-      opts.hostname !== "localhost" &&
-      opts.hostname !== "::1"
-    if (shouldPublishMDNS) {
-      MDNS.publish(server.port!)
-    } else if (opts.mdns) {
-      log.warn("mDNS enabled but hostname is loopback; skipping mDNS publish")
-    }
-
-    const originalStop = server.stop.bind(server)
-    server.stop = async (closeActiveConnections?: boolean) => {
-      if (shouldPublishMDNS) MDNS.unpublish()
-      return originalStop(closeActiveConnections)
-    }
-
-    return server
+    return Bun.serve({ ...args, port: opts.port })
   }
 }

+ 8 - 10
packages/web/src/content/docs/cli.mdx

@@ -335,11 +335,10 @@ This starts an HTTP server that provides API access to opencode functionality wi
 
 #### Flags
 
-| Flag         | Description           |
-| ------------ | --------------------- |
-| `--port`     | Port to listen on     |
-| `--hostname` | Hostname to listen on |
-| `--mdns`     | Enable mDNS discovery |
+| Flag         | Short | Description           |
+| ------------ | ----- | --------------------- |
+| `--port`     | `-p`  | Port to listen on     |
+| `--hostname` |       | Hostname to listen on |
 
 ---
 
@@ -429,11 +428,10 @@ This starts an HTTP server and opens a web browser to access OpenCode through a
 
 #### Flags
 
-| Flag         | Description           |
-| ------------ | --------------------- |
-| `--port`     | Port to listen on     |
-| `--hostname` | Hostname to listen on |
-| `--mdns`     | Enable mDNS discovery |
+| Flag         | Short | Description           |
+| ------------ | ----- | --------------------- |
+| `--port`     | `-p`  | Port to listen on     |
+| `--hostname` |       | Hostname to listen on |
 
 ---
 

+ 0 - 25
packages/web/src/content/docs/config.mdx

@@ -120,31 +120,6 @@ Available options:
 
 ---
 
-### Server
-
-You can configure server settings for the `opencode serve` and `opencode web` commands through the `server` option.
-
-```json title="opencode.json"
-{
-  "$schema": "https://opencode.ai/config.json",
-  "server": {
-    "port": 4096,
-    "hostname": "0.0.0.0",
-    "mdns": true
-  }
-}
-```
-
-Available options:
-
-- `port` - Port to listen on.
-- `hostname` - Hostname to listen on. When `mdns` is enabled and no hostname is set, defaults to `0.0.0.0`.
-- `mdns` - Enable mDNS service discovery. This allows other devices on the network to discover your OpenCode server.
-
-[Learn more about the server here](/docs/server).
-
----
-
 ### Tools
 
 You can manage the tools an LLM can use through the `tools` option.

+ 4 - 5
packages/web/src/content/docs/server.mdx

@@ -18,11 +18,10 @@ opencode serve [--port <number>] [--hostname <string>]
 
 #### Options
 
-| Flag         | Description           | Default     |
-| ------------ | --------------------- | ----------- |
-| `--port`     | Port to listen on     | `4096`      |
-| `--hostname` | Hostname to listen on | `127.0.0.1` |
-| `--mdns`     | Enable mDNS discovery | `false`     |
+| Flag         | Short | Description           | Default     |
+| ------------ | ----- | --------------------- | ----------- |
+| `--port`     | `-p`  | Port to listen on     | `4096`      |
+| `--hostname` | `-h`  | Hostname to listen on | `127.0.0.1` |
 
 ---