DorkOSDorkOS
Integrations

Building Integrations

Create custom clients using the DorkOS Transport interface

Building Integrations

DorkOS uses a hexagonal (ports & adapters) architecture centered on the Transport interface. You can build custom clients by implementing this interface or by using the REST/SSE API directly.

The Transport Interface

The Transport interface (packages/shared/src/transport.ts) defines all client-server communication:

interface Transport {
  createSession(opts: CreateSessionRequest): Promise<Session>;
  listSessions(cwd?: string): Promise<Session[]>;
  getSession(id: string, cwd?: string): Promise<Session>;
  updateSession(id: string, opts: UpdateSessionRequest, cwd?: string): Promise<Session>;
  getMessages(sessionId: string, cwd?: string): Promise<{ messages: HistoryMessage[] }>;
  sendMessage(sessionId, content, onEvent, signal?, cwd?): Promise<void>;
  approveTool(sessionId: string, toolCallId: string): Promise<{ ok: boolean }>;
  denyTool(sessionId: string, toolCallId: string): Promise<{ ok: boolean }>;
  submitAnswers(sessionId, toolCallId, answers): Promise<{ ok: boolean }>;
  getTasks(sessionId: string, cwd?: string): Promise<{ tasks: TaskItem[] }>;
  browseDirectory(dirPath?, showHidden?): Promise<BrowseDirectoryResponse>;
  getDefaultCwd(): Promise<{ path: string }>;
  getCommands(refresh?: boolean, cwd?: string): Promise<CommandRegistry>;
  listFiles(cwd: string): Promise<FileListResponse>;
  getGitStatus(cwd?: string): Promise<GitStatusResponse | GitStatusError>;
  health(): Promise<HealthResponse>;
  getConfig(): Promise<ServerConfig>;
}

Built-in Implementations

HttpTransport is used by the standalone web client and communicates with the Express server over HTTP and SSE:

  • Standard fetch() for CRUD operations
  • Server-Sent Events for streaming in sendMessage()
  • Parses SSE events into StreamEvent objects
  • Includes X-Client-Id header for session locking

DirectTransport is used by the Obsidian plugin and calls service instances directly in the same process:

  • No HTTP, no port binding, no network serialization
  • Iterates AsyncGenerator<StreamEvent> from the Agent SDK
  • Lower latency, ideal for embedded contexts

Building a Custom Client

Choose the approach that best fits your platform and requirements:

Use the REST API directly for any language or platform:

# List sessions
GET /api/sessions

# Create a session
POST /api/sessions
Content-Type: application/json
{ "cwd": "/path/to/project" }

# Send a message (returns SSE stream)
POST /api/sessions/:id/messages
Content-Type: application/json
{ "content": "Hello", "cwd": "/path/to/project" }

# Approve a tool call
POST /api/sessions/:id/approve
Content-Type: application/json
{ "toolCallId": "tc_123" }

The full REST API is documented interactively at /api/docs (Scalar UI) when the server is running, or see the API Reference.

Implement the Transport interface for deeper integration:

import type { Transport } from '@dorkos/shared/transport';

class MyCustomTransport implements Transport {
  async listSessions() {
    // Your implementation
  }

  async sendMessage(sessionId, content, onEvent, signal, cwd) {
    // Connect to your backend
    // Call onEvent() for each StreamEvent
  }

  // ... implement remaining methods
}

All methods in the Transport interface must be implemented. TypeScript will report compile-time errors for any missing methods.

If building a React app, inject your Transport via context:

import { TransportProvider } from '@dorkos/shared';

const transport = new MyCustomTransport();

function App() {
  return (
    <TransportProvider transport={transport}>
      <YourApp />
    </TransportProvider>
  );
}

All DorkOS hooks (useSessions, useChatSession, etc.) consume the Transport from context, so your custom implementation powers the entire UI automatically.

StreamEvent Types

Events emitted during message streaming:

Prop

Type

Next Steps