client.mdx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. ---
  2. title: "Client"
  3. description: "Connect an application to the OpenCode HTTP API."
  4. ---
  5. `@opencode-ai/client` is the generated TypeScript client for the OpenCode HTTP
  6. API. Use it when your application connects to an OpenCode server over the
  7. network. Its types and methods are generated from the same contract as the
  8. [API reference](/api).
  9. <Callout type="warning">
  10. The V2 API and client are beta. Method names, inputs, and outputs may change
  11. before the stable release.
  12. </Callout>
  13. ## Install
  14. ```sh
  15. bun add @opencode-ai/client@next
  16. ```
  17. ## Create a client
  18. Create a client with the server URL, then call methods grouped by API resource:
  19. ```ts
  20. import { OpenCode } from "@opencode-ai/client"
  21. const client = OpenCode.make({
  22. baseUrl: "http://localhost:4096",
  23. })
  24. const session = await client.session.create({
  25. location: { directory: "/workspace" },
  26. })
  27. await client.session.prompt({
  28. sessionID: session.id,
  29. text: "Review the current changes",
  30. })
  31. ```
  32. ## Headers and requests
  33. Pass default authentication or application headers to `OpenCode.make` with
  34. `headers`. You can also supply a custom `fetch` implementation. Each operation
  35. accepts request options as its final argument for an `AbortSignal` or
  36. per-request headers.
  37. ```ts
  38. const client = OpenCode.make({
  39. baseUrl: "https://opencode.example.com",
  40. headers: {
  41. authorization: `Bearer ${process.env.OPENCODE_TOKEN}`,
  42. },
  43. })
  44. await client.session.list(undefined, {
  45. signal: AbortSignal.timeout(10_000),
  46. })
  47. ```
  48. ## Stream events
  49. Streaming endpoints return async iterables:
  50. ```ts
  51. for await (const event of client.event.subscribe()) {
  52. console.log(event.type)
  53. }
  54. ```
  55. ## Local background service
  56. The main client entrypoints are browser-compatible and do not include local
  57. process management. In a Node application, import the native Promise service
  58. API from `@opencode-ai/client/service`.
  59. - `Service.discover()` returns a healthy registered endpoint without starting
  60. a process.
  61. - `Service.ensure()` returns a compatible service, starting one when needed.
  62. - `Service.stop()` stops the exact registered service instance.
  63. - `Service.headers(endpoint)` creates the authentication headers for a client.
  64. ```ts
  65. import { OpenCode } from "@opencode-ai/client"
  66. import { Service } from "@opencode-ai/client/service"
  67. const endpoint = await Service.ensure()
  68. const client = OpenCode.make({
  69. baseUrl: endpoint.url,
  70. headers: Service.headers(endpoint),
  71. })
  72. const health = await client.health.get()
  73. ```
  74. `Service.ensure()` accepts an optional registration file, required version,
  75. service command, and `onStart` callback:
  76. ```ts
  77. const endpoint = await Service.ensure({
  78. file: "/var/run/opencode/service.json",
  79. version: "2.0.0",
  80. command: ["opencode", "serve", "--service"],
  81. onStart(reason, previousVersion) {
  82. console.log(reason, previousVersion)
  83. },
  84. })
  85. ```
  86. Omit these options to use the standard registration path and
  87. `opencode serve --service` command.
  88. ## Effect
  89. OpenCode provides a first-class Effect client through the
  90. `@opencode-ai/client/effect` entrypoint. It returns typed Effects and Streams
  91. and decodes responses into OpenCode schema values.
  92. ```sh
  93. bun add @opencode-ai/client@next effect
  94. ```
  95. ### Create a client
  96. ```ts
  97. import { AbsolutePath, Location, OpenCode } from "@opencode-ai/client/effect"
  98. import { Effect } from "effect"
  99. import { FetchHttpClient } from "effect/unstable/http"
  100. const program = Effect.gen(function* () {
  101. const client = yield* OpenCode.make({ baseUrl: "http://localhost:4096" })
  102. const session = yield* client.session.create({
  103. location: Location.Ref.make({
  104. directory: AbsolutePath.make("/workspace"),
  105. }),
  106. })
  107. return yield* client.session.get({ sessionID: session.id })
  108. })
  109. const session = await Effect.runPromise(
  110. program.pipe(Effect.provide(FetchHttpClient.layer)),
  111. )
  112. ```
  113. Streaming operations, including `client.event.subscribe()` and
  114. `client.session.log(...)`, return Effect `Stream` values.
  115. ### Local background service
  116. The Node-only `@opencode-ai/client/effect/service` entrypoint exposes the same
  117. operations as Effect values. Add `@effect/platform-node` and provide its
  118. filesystem layer when running them.
  119. ```sh
  120. bun add @effect/platform-node
  121. ```
  122. ```ts
  123. import { NodeFileSystem } from "@effect/platform-node"
  124. import { OpenCode } from "@opencode-ai/client/effect"
  125. import { Service } from "@opencode-ai/client/effect/service"
  126. import { Effect } from "effect"
  127. import { FetchHttpClient } from "effect/unstable/http"
  128. const program = Effect.gen(function* () {
  129. const endpoint = yield* Service.ensure()
  130. const client = yield* OpenCode.make({
  131. baseUrl: endpoint.url,
  132. headers: Service.headers(endpoint),
  133. })
  134. return yield* client.health.get()
  135. })
  136. const health = await Effect.runPromise(
  137. program.pipe(
  138. Effect.provide(FetchHttpClient.layer),
  139. Effect.provide(NodeFileSystem.layer),
  140. ),
  141. )
  142. ```