# How to Implement a Custom Bot Adapter for Maka

> Learn how to implement a custom Bot Adapter for Maka by implementing ExternalSessionAdapter and registering it. Effortlessly manage bot sessions with your custom solution.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: how-to-guide
- Published: 2026-09-09

---

**Implement the `ExternalSessionAdapter` interface, expose a constructor accepting an options object, and register the adapter in the `ExternalSessionAdapterRegistry` to enable Maka to read, write, and list sessions from any custom bot.**

Maka treats any bot capable of reading, writing, or listing chat-like sessions as an **External Session Adapter**. According to the apache/maka source code, the core architecture resides in the `@maka/core` package (imported as `@maka/core/external-session`) and wires into the runtime through a centralized registry. By implementing a custom bot adapter, you can integrate proprietary LLM services, internal chatbots, or third-party APIs into Maka's session handling pipeline without modifying core framework logic.

## Understanding the External Session Adapter Architecture

The adapter architecture follows a three-tier pattern that decouples session storage from the importer logic.

First, your custom implementation adheres to the `ExternalSessionAdapter` interface defined in `@maka/core/external-session`. Second, the `ExternalSessionAdapterRegistry` (created via `createExternalSessionAdapterRegistry`) maintains an array of available adapters. Finally, the `ExternalSessionImporter` consumes this registry at runtime to route session operations to the appropriate adapter.

```

┌─────────────────────┐
│ Custom Bot Adapter  │   (implements ExternalSessionAdapter)
└───────┬─────────────┘
        │
        ▼
┌─────────────────────┐
│ ExternalSessionAdapterRegistry │  (holds an array of adapters)
└───────┬─────────────┘
        │
        ▼
┌─────────────────────┐
│ ExternalSessionImporter │ (loads sessions via the registry)
└─────────────────────┘

```

Reference implementations such as `OpenCodeSessionAdapter`, `CodexSessionAdapter`, and `ClaudeCodeSessionAdapter` demonstrate the required shape. The `OpenCodeSessionAdapter` source in [`packages/storage/src/opencode-session-adapter.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/opencode-session-adapter.ts) provides the most concrete baseline for new implementations.

## Implementing the ExternalSessionAdapter Interface

A valid custom bot adapter must implement five core methods: `listSessions()`, `readSession()`, `writeSession()`, `deleteSession()`, and optional metadata getters. All methods return Promises and operate on `SessionMetadata` and `SessionMessage` types.

Create a new file (e.g., [`my-bot-adapter.ts`](https://github.com/apache/maka/blob/main/my-bot-adapter.ts)) and implement the interface as follows:

```typescript
import type {
  ExternalSessionAdapter,
  SessionMetadata,
  SessionMessage,
  ExternalSessionError,
} from '@maka/core/external-session';

export interface MyBotAdapterOptions {
  /** Base URL of the bot service */
  apiUrl?: string;
  /** Optional auth token (do NOT hard‑code it) */
  authToken?: string;
  /** Maximum number of messages to keep per session */
  maxMessages?: number;
}

/** Simple in‑memory example – replace with real API calls */
export class MyBotAdapter implements ExternalSessionAdapter {
  private readonly options: Required<MyBotAdapterOptions>;

  constructor(options: MyBotAdapterOptions = {}) {
    this.options = {
      apiUrl: options.apiUrl ?? 'https://api.mybot.example',
      authToken: options.authToken ?? '',
      maxMessages: options.maxMessages ?? 100,
    };
  }

  /** List all stored session ids */
  async listSessions(): Promise<SessionMetadata[]> {
    // TODO: replace with real HTTP request
    return []; // placeholder
  }

  /** Read a session by its id */
  async readSession(id: string): Promise<SessionMessage[]> {
    // TODO: fetch from bot service, transform to SessionMessage[]
    return [];
  }

  /** Write a full session (overwrite) */
  async writeSession(
    id: string,
    messages: SessionMessage[],
  ): Promise<void> {
    // TODO: POST messages to the bot service (respect maxMessages)
  }

  /** Delete a session */
  async deleteSession(id: string): Promise<void> {
    // TODO: DELETE request to the bot service
  }

  /** Optional – provide human‑readable metadata */
  async getMetadata(id: string): Promise<SessionMetadata> {
    return {
      id,
      name: `MyBot Session ${id}`,
      cwd: '',
    };
  }
}

```

**Key implementation requirements:**

- **Async returns**: All interface methods must return Promises to allow the runner to interact uniformly with any bot.
- **Options object**: Accept a typed configuration object (e.g., `MyBotAdapterOptions`) containing API endpoints, authentication tokens, or filesystem paths rather than hard-coding values.
- **Error handling**: Throw `ExternalSessionError` (or a subclass) for recoverable failures; propagate unexpected errors to allow Maka to surface useful diagnostics.

## Registering Your Custom Bot Adapter

After implementing the interface, register the adapter in the global registry to make it discoverable by the importer. Modify [`packages/storage/src/external-session-adapters.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/external-session-adapters.ts) to include your adapter in the array passed to `new ExternalSessionAdapterRegistry()`.

```typescript
import { MyBotAdapter, type MyBotAdapterOptions } from './my-bot-adapter.js';
import { ExternalSessionAdapterRegistry } from '@maka/core/external-session';

// Existing adapters …
import { OpenCodeSessionAdapter, type OpenCodeSessionAdapterOptions } from './opencode-session-adapter.js';

export function createExternalSessionAdapterRegistry(
  options: {
    opencode?: OpenCodeSessionAdapterOptions;
    myBot?: MyBotAdapterOptions;   // ← new options
  } = {},
): ExternalSessionAdapterRegistry {
  return new ExternalSessionAdapterRegistry([
    // keep existing adapters
    new OpenCodeSessionAdapter(options.opencode),
    // add the custom bot adapter
    new MyBotAdapter(options.myBot),
  ]);
}

```

The registry factory pattern ensures that Maka's `ExternalSessionImporter` can locate and instantiate your adapter at runtime based on the configuration provided.

## Using the Adapter in Production

Once registered, consume the adapter through the `ExternalSessionImporter` class. The importer automatically routes session operations to the correct adapter based on the session ID and registry configuration.

```typescript
import { createExternalSessionAdapterRegistry } from '@maka/storage';
import { ExternalSessionImporter } from '@maka/storage';

// Create a registry that includes the custom bot
const registry = createExternalSessionAdapterRegistry({
  myBot: { apiUrl: 'https://api.mybot.example', authToken: process.env.MY_BOT_TOKEN },
});

// Import a session (e.g., by id) – the importer will route to the correct adapter
const importer = new ExternalSessionImporter(registry, { cwd: '/some/project' });

const session = await importer.importSession('my-bot-session-123');
console.log(session.messages);

```

## Error Handling and Best Practices

Follow these patterns to ensure compatibility with Maka's test suites and future updates:

1. **Throw specific errors**: Use `ExternalSessionError` for expected failure modes (network timeouts, authentication failures) to enable Maka's error recovery logic.
2. **Validate options**: Enforce required configuration inside the constructor and provide sensible defaults for optional parameters.
3. **Test coverage**: Model your test suite after [`packages/storage/src/__tests__/opencode-session-adapter.test.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/__tests__/opencode-session-adapter.test.ts), which exercises all adapter methods against mock data to verify compatibility.
4. **Session metadata**: Always return consistent `SessionMetadata` objects containing `id`, `name`, and `cwd` fields to ensure the UI can display session information correctly.

## Summary

- **Implement `ExternalSessionAdapter`**: Provide async methods for `listSessions`, `readSession`, `writeSession`, and `deleteSession` in a new class file.
- **Accept configuration**: Design the constructor to receive a typed options object for API URLs, tokens, and limits.
- **Register in factory**: Add your adapter instance to the array in `createExternalSessionAdapterRegistry` inside [`external-session-adapters.ts`](https://github.com/apache/maka/blob/main/external-session-adapters.ts).
- **Handle errors properly**: Throw `ExternalSessionError` for operational failures to integrate with Maka's diagnostic system.
- **Test thoroughly**: Use the existing [`opencode-session-adapter.test.ts`](https://github.com/apache/maka/blob/main/opencode-session-adapter.test.ts) pattern to validate your implementation against mock data.

## Frequently Asked Questions

### What methods are required to implement a custom bot adapter for Maka?

You must implement four core methods from the `ExternalSessionAdapter` interface: `listSessions()` to retrieve available sessions, `readSession(id)` to fetch message arrays, `writeSession(id, messages)` to persist data, and `deleteSession(id)` to remove sessions. An optional `getMetadata(id)` method provides human-readable session information for the UI.

### Where do I register a new custom bot adapter in the Maka codebase?

Register the adapter in [`packages/storage/src/external-session-adapters.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/external-session-adapters.ts) inside the `createExternalSessionAdapterRegistry` function. Import your adapter class, add its options to the function's parameter type, and instantiate it in the array passed to `new ExternalSessionAdapterRegistry()`.

### How does Maka route session operations to the correct custom adapter?

The `ExternalSessionImporter` class consumes the `ExternalSessionAdapterRegistry`, which holds all registered adapters. When you call `importSession()`, the importer queries the registry to locate the appropriate adapter instance and delegates the read or write operation to it.

### Can I use environment variables to configure my custom bot adapter?

Yes. Pass environment variables through the options object in `createExternalSessionAdapterRegistry`. For example, provide `authToken: process.env.MY_BOT_TOKEN` in the options object when instantiating your adapter, keeping sensitive credentials out of source code while maintaining runtime configurability.