Back to Opencode

Server

packages/web/src/content/docs/server.mdx

1.14.3917.7 KB
Original Source

import config from "../../../config.mjs" export const typesUrl = ${config.github}/blob/dev/packages/sdk/js/src/gen/types.gen.ts

The opencode serve command runs a headless HTTP server that exposes an OpenAPI endpoint that an opencode client can use.


Usage

bash
opencode serve [--port <number>] [--hostname <string>] [--cors <origin>]

Options

FlagDescriptionDefault
--portPort to listen on4096
--hostnameHostname to listen on127.0.0.1
--mdnsEnable mDNS discoveryfalse
--mdns-domainCustom domain name for mDNS serviceopencode.local
--corsAdditional browser origins to allow[]

--cors can be passed multiple times:

bash
opencode serve --cors http://localhost:5173 --cors https://app.example.com

Authentication

Set OPENCODE_SERVER_PASSWORD to protect the server with HTTP basic auth. The username defaults to opencode, or set OPENCODE_SERVER_USERNAME to override it. This applies to both opencode serve and opencode web.

bash
OPENCODE_SERVER_PASSWORD=your-password opencode serve

How it works

When you run opencode it starts a TUI and a server. Where the TUI is the client that talks to the server. The server exposes an OpenAPI 3.1 spec endpoint. This endpoint is also used to generate an SDK.

:::tip Use the opencode server to interact with opencode programmatically. :::

This architecture lets opencode support multiple clients and allows you to interact with opencode programmatically.

You can run opencode serve to start a standalone server. If you have the opencode TUI running, opencode serve will start a new server.


Connect to an existing server

When you start the TUI it randomly assigns a port and hostname. You can instead pass in the --hostname and --port flags. Then use this to connect to its server.

The /tui endpoint can be used to drive the TUI through the server. For example, you can prefill or run a prompt. This setup is used by the OpenCode IDE plugins.


Spec

The server publishes an OpenAPI 3.1 spec that can be viewed at:

http://<hostname>:<port>/doc

For example, http://localhost:4096/doc. Use the spec to generate clients or inspect request and response types. Or view it in a Swagger explorer.


APIs

The opencode server exposes the following APIs.


Global

MethodPathDescriptionResponse
GET/global/healthGet server health and version{ healthy: true, version: string }
GET/global/eventGet global events (SSE stream)Event stream

Project

MethodPathDescriptionResponse
GET/projectList all projects<a href={typesUrl}><code>Project[]</code></a>
GET/project/currentGet the current project<a href={typesUrl}><code>Project</code></a>

Path & VCS

MethodPathDescriptionResponse
GET/pathGet the current path<a href={typesUrl}><code>Path</code></a>
GET/vcsGet VCS info for the current project<a href={typesUrl}><code>VcsInfo</code></a>

Instance

MethodPathDescriptionResponse
POST/instance/disposeDispose the current instanceboolean

Config

MethodPathDescriptionResponse
GET/configGet config info<a href={typesUrl}><code>Config</code></a>
PATCH/configUpdate config<a href={typesUrl}><code>Config</code></a>
GET/config/providersList providers and default models{ providers: <a href={typesUrl}>Provider[]</a>, default: { [key: string]: string } }

Provider

MethodPathDescriptionResponse
GET/providerList all providers{ all: <a href={typesUrl}>Provider[]</a>, default: {...}, connected: string[] }
GET/provider/authGet provider authentication methods{ [providerID: string]: <a href={typesUrl}>ProviderAuthMethod[]</a> }
POST/provider/{id}/oauth/authorizeAuthorize a provider using OAuth<a href={typesUrl}><code>ProviderAuthAuthorization</code></a>
POST/provider/{id}/oauth/callbackHandle OAuth callback for a providerboolean

Sessions

MethodPathDescriptionNotes
GET/sessionList all sessionsReturns <a href={typesUrl}><code>Session[]</code></a>
POST/sessionCreate a new sessionbody: { parentID?, title? }, returns <a href={typesUrl}><code>Session</code></a>
GET/session/statusGet session status for all sessionsReturns { [sessionID: string]: <a href={typesUrl}>SessionStatus</a> }
GET/session/:idGet session detailsReturns <a href={typesUrl}><code>Session</code></a>
DELETE/session/:idDelete a session and all its dataReturns boolean
PATCH/session/:idUpdate session propertiesbody: { title? }, returns <a href={typesUrl}><code>Session</code></a>
GET/session/:id/childrenGet a session's child sessionsReturns <a href={typesUrl}><code>Session[]</code></a>
GET/session/:id/todoGet the todo list for a sessionReturns <a href={typesUrl}><code>Todo[]</code></a>
POST/session/:id/initAnalyze app and create AGENTS.mdbody: { messageID, providerID, modelID }, returns boolean
POST/session/:id/forkFork an existing session at a messagebody: { messageID? }, returns <a href={typesUrl}><code>Session</code></a>
POST/session/:id/abortAbort a running sessionReturns boolean
POST/session/:id/shareShare a sessionReturns <a href={typesUrl}><code>Session</code></a>
DELETE/session/:id/shareUnshare a sessionReturns <a href={typesUrl}><code>Session</code></a>
GET/session/:id/diffGet the diff for this sessionquery: messageID?, returns <a href={typesUrl}><code>FileDiff[]</code></a>
POST/session/:id/summarizeSummarize the sessionbody: { providerID, modelID }, returns boolean
POST/session/:id/revertRevert a messagebody: { messageID, partID? }, returns boolean
POST/session/:id/unrevertRestore all reverted messagesReturns boolean
POST/session/:id/permissions/:permissionIDRespond to a permission requestbody: { response, remember? }, returns boolean

Messages

MethodPathDescriptionNotes
GET/session/:id/messageList messages in a sessionquery: limit?, returns { info: <a href={typesUrl}>Message</a>, parts: <a href={typesUrl}>Part[]</a>}[]
POST/session/:id/messageSend a message and wait for responsebody: { messageID?, model?, agent?, noReply?, system?, tools?, parts }, returns { info: <a href={typesUrl}>Message</a>, parts: <a href={typesUrl}>Part[]</a>}
GET/session/:id/message/:messageIDGet message detailsReturns { info: <a href={typesUrl}>Message</a>, parts: <a href={typesUrl}>Part[]</a>}
POST/session/:id/prompt_asyncSend a message asynchronously (no wait)body: same as /session/:id/message, returns 204 No Content
POST/session/:id/commandExecute a slash commandbody: { messageID?, agent?, model?, command, arguments }, returns { info: <a href={typesUrl}>Message</a>, parts: <a href={typesUrl}>Part[]</a>}
POST/session/:id/shellRun a shell commandbody: { agent, model?, command }, returns { info: <a href={typesUrl}>Message</a>, parts: <a href={typesUrl}>Part[]</a>}

Commands

MethodPathDescriptionResponse
GET/commandList all commands<a href={typesUrl}><code>Command[]</code></a>

Files

MethodPathDescriptionResponse
GET/find?pattern=<pat>Search for text in filesArray of match objects with path, lines, line_number, absolute_offset, submatches
GET/find/file?query=<q>Find files and directories by namestring[] (paths)
GET/find/symbol?query=<q>Find workspace symbols<a href={typesUrl}><code>Symbol[]</code></a>
GET/file?path=<path>List files and directories<a href={typesUrl}><code>FileNode[]</code></a>
GET/file/content?path=<p>Read a file<a href={typesUrl}><code>FileContent</code></a>
GET/file/statusGet status for tracked files<a href={typesUrl}><code>File[]</code></a>

/find/file query parameters

  • query (required) — search string (fuzzy match)
  • type (optional) — limit results to "file" or "directory"
  • directory (optional) — override the project root for the search
  • limit (optional) — max results (1–200)
  • dirs (optional) — legacy flag ("false" returns only files)

Tools (Experimental)

MethodPathDescriptionResponse
GET/experimental/tool/idsList all tool IDs<a href={typesUrl}><code>ToolIDs</code></a>
GET/experimental/tool?provider=<p>&model=<m>List tools with JSON schemas for a model<a href={typesUrl}><code>ToolList</code></a>

LSP, Formatters & MCP

MethodPathDescriptionResponse
GET/lspGet LSP server status<a href={typesUrl}><code>LSPStatus[]</code></a>
GET/formatterGet formatter status<a href={typesUrl}><code>FormatterStatus[]</code></a>
GET/mcpGet MCP server status{ [name: string]: <a href={typesUrl}>MCPStatus</a> }
POST/mcpAdd MCP server dynamicallybody: { name, config }, returns MCP status object

Agents

MethodPathDescriptionResponse
GET/agentList all available agents<a href={typesUrl}><code>Agent[]</code></a>

Logging

MethodPathDescriptionResponse
POST/logWrite log entry. Body: { service, level, message, extra? }boolean

TUI

MethodPathDescriptionResponse
POST/tui/append-promptAppend text to the promptboolean
POST/tui/open-helpOpen the help dialogboolean
POST/tui/open-sessionsOpen the session selectorboolean
POST/tui/open-themesOpen the theme selectorboolean
POST/tui/open-modelsOpen the model selectorboolean
POST/tui/submit-promptSubmit the current promptboolean
POST/tui/clear-promptClear the promptboolean
POST/tui/execute-commandExecute a command ({ command })boolean
POST/tui/show-toastShow toast ({ title?, message, variant })boolean
GET/tui/control/nextWait for the next control requestControl request object
POST/tui/control/responseRespond to a control request ({ body })boolean

Auth

MethodPathDescriptionResponse
PUT/auth/:idSet authentication credentials. Body must match provider schemaboolean

Events

MethodPathDescriptionResponse
GET/eventServer-sent events stream. First event is server.connected, then bus eventsServer-sent events stream

Docs

MethodPathDescriptionResponse
GET/docOpenAPI 3.1 specificationHTML page with OpenAPI spec