OpenCode OpenCode

Develop

Build integrations and extend OpenCode with the SDK, server, plugins, and ecosystem.

SDK

Type-safe JS client for opencode server.

The opencode JS/TS SDK provides a type-safe client for interacting with the server. Use it to build integrations and control opencode programmatically.

Learn more about how the server works in Server. For examples, check out the projects built by the community in Ecosystem.


Install

Install the SDK from npm:

Terminal
npm install @opencode-ai/sdk

Create client

Create an instance of opencode:

JavaScript
import { createOpencode } from "@opencode-ai/sdk"
const { client } = await createOpencode()

This starts both a server and a client.

Options

OptionTypeDescriptionDefault
hostnamestringServer hostname127.0.0.1
portnumberServer port4096
signalAbortSignalAbort signal for cancellationundefined
timeoutnumberTimeout in ms for server start5000
configConfigConfiguration object{}

Config

You can pass a configuration object to customize behavior. The instance still picks up your opencode.json, but you can override or add configuration inline:

JavaScript
import { createOpencode } from "@opencode-ai/sdk"
const opencode = await createOpencode({
  hostname: "127.0.0.1",
  port: 4096,
  config: {
    model: "anthropic/claude-3-5-sonnet-20241022",
  },
})
console.log(`Server running at ${opencode.server.url}`)
opencode.server.close()

Client only

If you already have a running instance of opencode, you can create a client instance to connect to it:

JavaScript
import { createOpencodeClient } from "@opencode-ai/sdk"
const client = createOpencodeClient({
  baseUrl: "http://localhost:4096",
})

Options

OptionTypeDescriptionDefault
baseUrlstringURL of the serverhttp://localhost:4096
fetchfunctionCustom fetch implementationglobalThis.fetch
parseAsstringResponse parsing methodauto
responseStylestringReturn style: data or fieldsfields
throwOnErrorbooleanThrow errors instead of returnfalse

Types

The SDK includes TypeScript definitions for all API types. Import them directly:

TypeScript
import type { Session, Message, Part } from "@opencode-ai/sdk"

All types are generated from the server's OpenAPI specification and available in the types file.


Errors

The SDK can throw errors that you can catch and handle:

JavaScript
try {
  await client.session.get({ path: { id: "invalid-id" } })
} catch (error) {
  console.error("Failed to get session:", (error as Error).message)
}

Structured Output

You can request structured JSON output from the model by specifying a format with a JSON schema. The model will use a StructuredOutput tool to return validated JSON matching your schema.

Basic Usage

JavaScript
const result = await client.session.prompt({
  path: { id: sessionId },
  body: {
    parts: [{ type: "text", text: "Research Anthropic and provide company info" }],
    format: {
      type: "json_schema",
      schema: {
        type: "object",
        properties: {
          company: { type: "string", description: "Company name" },
          founded: { type: "number", description: "Year founded" },
          products: {
            type: "array",
            items: { type: "string" },
            description: "Main products",
          },
        },
        required: ["company", "founded"],
      },
    },
  },
})

// Access the structured output
console.log(result.data.info.structured_output)
// { company: "Anthropic", founded: 2021, products: ["Claude", "Claude API"] }

Output Format Types

TypeDescription
textDefault. Standard text response (no structured output)
json_schemaReturns validated JSON matching the provided schema

JSON Schema Format

When using type: 'json_schema', provide:

FieldTypeDescription
type'json_schema'Required. Specifies JSON schema mode
schemaobjectRequired. JSON Schema object defining the output structure
retryCountnumberOptional. Number of validation retries (default: 2)

Error Handling

If the model fails to produce valid structured output after all retries, the response will include a StructuredOutputError:

JavaScript
if (result.data.info.error?.name === "StructuredOutputError") {
  console.error("Failed to produce structured output:", result.data.info.error.message)
  console.error("Attempts:", result.data.info.error.retries)
}

Best Practices

  1. Provide clear descriptions in your schema properties to help the model understand what data to extract
  2. Use required to specify which fields must be present
  3. Keep schemas focused — complex nested schemas may be harder for the model to fill correctly
  4. Set appropriate retryCount — increase for complex schemas, decrease for simple ones

APIs

The SDK exposes all server APIs through a type-safe client.

Global

MethodDescriptionResponse
global.health()Check server health and version{ healthy: true, version: string }
JavaScript
const health = await client.global.health()
console.log(health.data.version)

App

MethodDescriptionResponse
app.log()Write a log entryboolean
app.agents()List all available agentsAgent[]
JavaScript
// Write a log entry
await client.app.log({
  body: {
    service: "my-app",
    level: "info",
    message: "Operation completed",
  },
})

// List available agents
const agents = await client.app.agents()

Project

MethodDescriptionResponse
project.list()List all projectsProject[]
project.current()Get current projectProject
JavaScript
// List all projects
const projects = await client.project.list()

// Get current project
const currentProject = await client.project.current()

Path

MethodDescriptionResponse
path.get()Get current pathPath
JavaScript
const pathInfo = await client.path.get()

Config

MethodDescriptionResponse
config.get()Get config infoConfig
config.providers()List providers and default models{ providers: Provider[], default: { [key: string]: string } }
JavaScript
const config = await client.config.get()

const { providers, default: defaults } = await client.config.providers()

Sessions

MethodDescriptionNotes
session.list()List sessionsReturns Session[]
session.get({ path })Get sessionReturns Session
session.children({ path })List child sessionsReturns Session[]
session.create({ body })Create sessionReturns Session
session.delete({ path })Delete sessionReturns boolean
session.update({ path, body })Update session propertiesReturns Session
session.init({ path, body })Analyze app and create AGENTS.mdReturns boolean
session.abort({ path })Abort a running sessionReturns boolean
session.share({ path })Share sessionReturns Session
session.unshare({ path })Unshare sessionReturns Session
session.summarize({ path, body })Summarize sessionReturns boolean
session.messages({ path })List messages in a sessionReturns { info: Message, parts: Part[] }[]
session.message({ path })Get message detailsReturns { info: Message, parts: Part[] }
session.prompt({ path, body })Send prompt messagebody.noReply: true returns UserMessage (context only). Default returns AssistantMessage with AI response. Supports body.outputFormat for structured output
session.command({ path, body })Send command to sessionReturns { info: AssistantMessage, parts: Part[] }
session.shell({ path, body })Run a shell commandReturns AssistantMessage
session.revert({ path, body })Revert a messageReturns Session
session.unrevert({ path })Restore reverted messagesReturns Session
JavaScript
// Create and manage sessions
const session = await client.session.create({
  body: { title: "My session" },
})

const sessions = await client.session.list()

// Send a prompt message
const result = await client.session.prompt({
  path: { id: session.id },
  body: {
    model: { providerID: "anthropic", modelID: "claude-3-5-sonnet-20241022" },
    parts: [{ type: "text", text: "Hello!" }],
  },
})

// Inject context without triggering AI response (useful for plugins)
await client.session.prompt({
  path: { id: session.id },
  body: {
    noReply: true,
    parts: [{ type: "text", text: "You are a helpful assistant." }],
  },
})

Files

MethodDescriptionResponse
find.text({ query })Search for text in filesArray of match objects with path, lines, line_number, absolute_offset, submatches
find.files({ query })Find files and directories by namestring[] (paths)
find.symbols({ query })Find workspace symbolsSymbol[]
file.read({ query })Read a file{ type: "raw" | "patch", content: string }
file.status({ query? })Get status for tracked filesFile[]

find.files supports a few optional query fields:

JavaScript
// Search and read files
const textResults = await client.find.text({
  query: { pattern: "function.*opencode" },
})

const files = await client.find.files({
  query: { query: "*.ts", type: "file" },
})

const directories = await client.find.files({
  query: { query: "packages", type: "directory", limit: 20 },
})

const content = await client.file.read({
  query: { path: "src/index.ts" },
})

TUI

MethodDescriptionResponse
tui.appendPrompt({ body })Append text to the promptboolean
tui.openHelp()Open the help dialogboolean
tui.openSessions()Open the session selectorboolean
tui.openThemes()Open the theme selectorboolean
tui.openModels()Open the model selectorboolean
tui.submitPrompt()Submit the current promptboolean
tui.clearPrompt()Clear the promptboolean
tui.executeCommand({ body })Execute a commandboolean
tui.showToast({ body })Show toast notificationboolean
JavaScript
// Control TUI interface
await client.tui.appendPrompt({
  body: { text: "Add this to prompt" },
})

await client.tui.showToast({
  body: { message: "Task completed", variant: "success" },
})

Auth

MethodDescriptionResponse
auth.set({ ... })Set authentication credentialsboolean
JavaScript
await client.auth.set({
  path: { id: "anthropic" },
  body: { type: "api", key: "your-api-key" },
})

Events

MethodDescriptionResponse
event.subscribe()Server-sent events streamServer-sent events stream
JavaScript
// Listen to real-time events
const events = await client.event.subscribe()
for await (const event of events.stream) {
  console.log("Event:", event.type, event.properties)
}

Server

Interact with opencode server over HTTP.

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


Usage

Terminal
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[]
Terminal
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.

Terminal
OPENCODE_SERVER_PASSWORD=your-password opencode serve

How it works

When you run opencode it starts a TUI and a server. 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, 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

MethodEndpointDescription
GET/global/healthGet server health and version
GET/global/eventGet global events (SSE stream)

Project

MethodEndpointDescription
GET/projectList all projects
GET/project/currentGet the current project

Path & VCS

MethodEndpointDescription
GET/pathGet the current path
GET/vcsGet VCS info for the current project

Instance

MethodEndpointDescription
POST/instance/disposeDispose the current instance

Config

MethodEndpointDescription
GET/configGet config info
PATCH/configUpdate config
GET/config/providersList providers and default models

Provider

MethodEndpointDescription
GET/providerList all providers
GET/provider/authGet provider authentication methods
POST/provider/{id}/oauth/authorizeAuthorize a provider using OAuth
POST/provider/{id}/oauth/callbackHandle OAuth callback

Sessions

MethodEndpointDescription
GET/sessionList all sessions
POST/sessionCreate a new session
GET/session/statusGet session status for all sessions
GET/session/:idGet session details
DELETE/session/:idDelete a session
PATCH/session/:idUpdate session properties
GET/session/:id/childrenGet child sessions
GET/session/:id/todoGet todo list
POST/session/:id/initAnalyze app and create AGENTS.md
POST/session/:id/forkFork existing session
POST/session/:id/abortAbort running session
POST/session/:id/shareShare a session
DELETE/session/:id/shareUnshare a session
GET/session/:id/diffGet diff for session
POST/session/:id/summarizeSummarize session
POST/session/:id/revertRevert a message
POST/session/:id/unrevertRestore reverted messages
POST/session/:id/permissions/:permissionIDRespond to permission request

Messages

MethodEndpointDescription
GET/session/:id/messageList messages in session
POST/session/:id/messageSend message and wait for response
GET/session/:id/message/:messageIDGet message details
POST/session/:id/prompt_asyncSend message asynchronously
POST/session/:id/commandExecute slash command
POST/session/:id/shellRun shell command

Commands

MethodEndpointDescription
GET/commandList all commands

Files

MethodEndpointDescription
GET/find?pattern=<pat>Search for text in files
GET/find/file?query=<q>Find files and directories by name
GET/find/symbol?query=<q>Find workspace symbols
GET/file?path=<path>List files and directories
GET/file/content?path=<p>Read a file
GET/file/statusGet status for tracked files

/find/file query parameters:

Tools (Experimental)

MethodEndpointDescription
GET/experimental/tool/idsList all tool IDs
GET/experimental/tool?provider=<p>&model=<m>List tools with JSON schemas

LSP, Formatters & MCP

MethodEndpointDescription
GET/lspGet LSP server status
GET/formatterGet formatter status
GET/mcpGet MCP server status
POST/mcpAdd MCP server dynamically

Agents

MethodEndpointDescription
GET/agentList all available agents

Logging

MethodEndpointDescription
POST/logWrite log entry

TUI

MethodEndpointDescription
POST/tui/append-promptAppend text to prompt
POST/tui/open-helpOpen help dialog
POST/tui/open-sessionsOpen session selector
POST/tui/open-themesOpen theme selector
POST/tui/open-modelsOpen model selector
POST/tui/submit-promptSubmit current prompt
POST/tui/clear-promptClear prompt
POST/tui/execute-commandExecute command
POST/tui/show-toastShow toast
GET/tui/control/nextWait for next control request
POST/tui/control/responseRespond to control request

Auth

MethodEndpointDescription
PUT/auth/:idSet authentication credentials

Events

MethodEndpointDescription
GET/eventServer-sent events stream

Docs

MethodEndpointDescription
GET/docOpenAPI 3.1 specification

Plugins

Write your own plugins to extend OpenCode.

Plugins allow you to extend OpenCode by hooking into various events and customizing behavior. You can create plugins to add new features, integrate with external services, or modify OpenCode's default behavior.


Use a plugin

There are two ways to load plugins.

From local files

Place JavaScript or TypeScript files in the plugin directory.

Files in these directories are automatically loaded at startup.

From npm

Specify npm packages in your config file.

opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}

Both regular and scoped npm packages are supported.

Browse available plugins in the Ecosystem.

How plugins are installed

npm plugins are installed automatically using Bun at startup. Packages and their dependencies are cached in ~/.cache/opencode/node_modules/.

Local plugins are loaded directly from the plugin directory. To use external packages, you must create a package.json within your config directory (see Dependencies), or publish the plugin to npm and add it to your config.

Load order

Plugins are loaded from all sources and all hooks run in sequence. The load order is:

  1. Global config (~/.config/opencode/opencode.json)
  2. Project config (opencode.json)
  3. Global plugin directory (~/.config/opencode/plugins/)
  4. Project plugin directory (.opencode/plugins/)

Duplicate npm packages with the same name and version are loaded once. However, a local plugin and an npm plugin with similar names are both loaded separately.

Dependencies

Local plugins and custom tools can use external npm packages. Add a package.json to your config directory with the dependencies you need.

package.json
{
  "dependencies": {
    "shescape": "^2.1.0"
  }
}

OpenCode runs bun install at startup to install these. Your plugins and tools can then import them.

TypeScript
import { escape } from "shescape"
export const MyPlugin = async (ctx) => {
  return {
    "tool.execute.before": async (input, output) => {
      if (input.tool === "bash") {
        output.args.command = escape(output.args.command)
      }
    },
  }
}

Create a plugin

Basic structure

A plugin is a JavaScript/TypeScript module that exports one or more plugin functions. Each function receives a context object and returns a hooks object.

JavaScript
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
  console.log("Plugin initialized!")
  return {
    // Hook implementations go here
  }
}

The plugin function receives:

TypeScript support

For TypeScript plugins, you can import types from the plugin package:

TypeScript
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
  return {
    // Type-safe hook implementations
  }
}

Events

Plugins can subscribe to events as seen below in the Examples section. Here is a list of the different events available.

Command Events: command.executed

File Events: file.edited, file.watcher.updated

Installation Events: installation.updated

LSP Events: lsp.client.diagnostics, lsp.updated

Message Events: message.part.removed, message.part.updated, message.removed, message.updated

Permission Events: permission.asked, permission.replied

Server Events: server.connected

Session Events: session.created, session.compacted, session.deleted, session.diff, session.error, session.idle, session.status, session.updated

Todo Events: todo.updated

Shell Events: shell.env

Tool Events: tool.execute.after, tool.execute.before

TUI Events: tui.prompt.append, tui.command.execute, tui.toast.show


Examples

Send notifications

Send notifications when certain events occur:

JavaScript
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
  return {
    event: async ({ event }) => {
      // Send notification on session completion
      if (event.type === "session.idle") {
        await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
      }
    },
  }
}

We are using osascript to run AppleScript on macOS. Here we are using it to send notifications.

Note

If you're using the OpenCode desktop app, it can send system notifications automatically when a response is ready or when a session errors.

.env protection

Prevent opencode from reading .env files:

JavaScript
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
  return {
    "tool.execute.before": async (input, output) => {
      if (input.tool === "read" && output.args.filePath.includes(".env")) {
        throw new Error("Do not read .env files")
      }
    },
  }
}

Inject environment variables

Inject environment variables into all shell execution (AI tools and user terminals):

JavaScript
export const InjectEnvPlugin = async () => {
  return {
    "shell.env": async (input, output) => {
      output.env.MY_API_KEY = "secret"
      output.env.PROJECT_ROOT = input.cwd
    },
  }
}

Custom tools

Plugins can also add custom tools to opencode:

TypeScript
import { type Plugin, tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => {
  return {
    tool: {
      mytool: tool({
        description: "This is a custom tool",
        args: {
          foo: tool.schema.string(),
        },
        async execute(args, context) {
          const { directory, worktree } = context
          return `Hello ${args.foo} from ${directory} (worktree: ${worktree})`
        },
      }),
    },
  }
}

The tool helper creates a custom tool that opencode can call. It takes a Zod schema function and returns a tool definition with:

Your custom tools will be available to opencode alongside built-in tools.

Note

If a plugin tool uses the same name as a built-in tool, the plugin tool takes precedence.

Logging

Use client.app.log() instead of console.log for structured logging:

TypeScript
export const MyPlugin = async ({ client }) => {
  await client.app.log({
    body: {
      service: "my-plugin",
      level: "info",
      message: "Plugin initialized",
      extra: { foo: "bar" },
    },
  })
}

Levels: debug, info, warn, error. See SDK documentation for details.

Compaction hooks

Customize the context included when a session is compacted:

TypeScript
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
  return {
    "experimental.session.compacting": async (input, output) => {
      // Inject additional context into the compaction prompt
      output.context.push(`## Custom Context
Include any state that should persist across compaction:
- Current task status
- Important decisions made
- Files being actively worked on`)
    },
  }
}

The experimental.session.compacting hook fires before the LLM generates a continuation summary. Use it to inject domain-specific context that the default compaction prompt would miss.

You can also replace the compaction prompt entirely by setting output.prompt:

TypeScript
import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => {
  return {
    "experimental.session.compacting": async (input, output) => {
      // Replace the entire compaction prompt
      output.prompt = `You are generating a continuation prompt for a multi-agent swarm session.
Summarize:
1. The current task and its status
2. Which files are being modified and by whom
3. Any blockers or dependencies between agents
4. The next steps to complete the work

Format as a structured prompt that a new agent can use to resume work.`
    },
  }
}

When output.prompt is set, it completely replaces the default compaction prompt. The output.context array is ignored in this case.

Ecosystem

Projects and integrations built with OpenCode.

A collection of community projects built on OpenCode.

Note

Want to add your OpenCode related project to this list? Submit a PR.

You can also check out awesome-opencode and opencode.cafe, a community that aggregates the ecosystem and community.


Plugins

NameDescription
opencode-daytonaAutomatically run OpenCode sessions in isolated Daytona sandboxes with git sync and live previews
opencode-helicone-sessionAutomatically inject Helicone session headers for request grouping
opencode-type-injectAuto-inject TypeScript/Svelte types into file reads with lookup tools
opencode-openai-codex-authUse your ChatGPT Plus/Pro subscription instead of API credits
opencode-gemini-authUse your existing Gemini plan instead of API billing
opencode-antigravity-authUse Antigravity's free models instead of API billing
opencode-devcontainersMulti-branch devcontainer isolation with shallow clones and auto-assigned ports
opencode-google-antigravity-authGoogle Antigravity OAuth Plugin, with support for Google Search
opencode-dynamic-context-pruningOptimize token usage by pruning obsolete tool outputs
opencode-vibeguardRedact secrets/PII into placeholders before LLM calls; restore locally
opencode-websearch-citedAdd native websearch support for supported providers with Google grounded style
opencode-ptyEnables AI agents to run background processes in a PTY, send interactive input
opencode-shell-strategyInstructions for non-interactive shell commands — prevents hangs from TTY-dependent operations
opencode-wakatimeTrack OpenCode usage with Wakatime
opencode-md-table-formatterClean up markdown tables produced by LLMs
opencode-morph-fast-apply10x faster code editing with Morph Fast Apply API and lazy edit markers
opencode-morph-pluginFast Apply editing, WarpGrep codebase search, and context compaction via Morph
oh-my-opencodeBackground agents, pre-built LSP/AST/MCP tools, curated agents, Claude Code compatible
opencode-notificatorDesktop notifications and sound alerts for OpenCode sessions
opencode-notifierDesktop notifications and sound alerts for permission, completion, and error events
opencode-zellij-namerAI-powered automatic Zellij session naming based on OpenCode context
opencode-skillfulAllow OpenCode agents to lazy load prompts on demand with skill discovery and injection
opencode-supermemoryPersistent memory across sessions using Supermemory
@plannotator/opencodeInteractive plan review with visual annotation and private/offline sharing
@openspoon/subtask2Extend opencode /commands into a powerful orchestration system with granular flow control
opencode-schedulerSchedule recurring jobs using launchd (Mac) or systemd (Linux) with cron syntax
opencode-conductorProtocol-Driven Workflow: Context → Spec → Plan → Implement lifecycle
micodeStructured Brainstorm → Plan → Implement workflow with session continuity
octtoInteractive browser UI for AI brainstorming with multi-question forms
opencode-background-agentsClaude Code-style background agents with async delegation and context persistence
opencode-notifyNative OS notifications for OpenCode — know when tasks complete
opencode-workspaceBundled multi-agent orchestration harness — 16 components, one install
opencode-worktreeZero-friction git worktrees for OpenCode
opencode-sentry-monitorTrace and debug your AI agents with Sentry AI Monitoring
opencode-firecrawlWeb scraping, crawling, and search via the Firecrawl CLI
opencode-jfrog-pluginJFrog Plugin for seamless integration of Opencode users to JFrog platform
opencode-goal-pluginSession-scoped /goal workflow that keeps objectives in context and auto-continues until complete

Projects

NameDescription
kimakiDiscord bot to control OpenCode sessions, built on the SDK
opencode.nvimNeovim plugin for editor-aware prompts, built on the API
portalMobile-first web UI for OpenCode over Tailscale/VPN
opencode plugin templateTemplate for building OpenCode plugins
opencode.nvimNeovim frontend for opencode — a terminal-based AI coding agent
ai-sdk-provider-opencode-sdkVercel AI SDK provider for using OpenCode via @opencode-ai/sdk
OpenChamberWeb / Desktop App and VS Code Extension for OpenCode
OpenCode-ObsidianObsidian plugin that embeds OpenCode in Obsidian's UI
OpenWorkAn open-source alternative to Claude Cowork, powered by OpenCode
ocxOpenCode extension manager with portable, isolated profiles
CodeNomadDesktop, Web, Mobile and Remote Client App for OpenCode

Agents

NameDescription
AgenticModular AI agents and commands for structured development
opencode-agentsConfigs, prompts, agents, and plugins for enhanced workflows