Skip to main content
This page covers the adapter-specific parts of writing a custom module. For the shared mechanics (file layout, registration, lifecycle) see Writing a custom module. For the full interface reference see AdapterModule.

Minimal Skeleton

import type { AdapterModule, InvokeInput, ModuleSetupContext, ServiceDefinition, ServiceState } from "@cyrnel/sdk";

class MyAdapter implements AdapterModule {
  private state = new Map<string, ServiceState>();

  async setup(_context: ModuleSetupContext) {}
  async teardown() { this.state.clear(); }

  async generateDefinition(input: string): Promise<ServiceDefinition> {
    return {
      name: "...",
      description: "...",
      configSchema: { type: "object", properties: {} },
      secretsSchema: { type: "object", properties: {} },
      adapterDomain: { /* parsed metadata */ },
      tools: [
        {
          id: "ping",
          name: "ping",
          description: "Health check",
          inputSchema: { type: "object" },
          outputSchema: { type: "object" },
          adapterDomain: { /* per-tool routing info */ },
        },
      ],
    };
  }

  async hydrateService(state: ServiceState): Promise<void> {
    this.state.set(state.id, state);
  }

  async dehydrateService(id: string): Promise<void> {
    this.state.delete(id);
  }

  async invoke(input: InvokeInput): Promise<unknown> {
    const svc = this.state.get(input.serviceId);
    if (!svc) throw new Error(`unknown service ${input.serviceId}`);
    // ...use svc.adapterDomain / svc.config / svc.secrets to issue the call
    return { ok: true };
  }
}

const configSchema = { type: "object", properties: {} } as const;
const secretsSchema = { type: "null" } as const;

export default { configSchema, secretsSchema, instantiate: () => new MyAdapter() };

Full Example

See the HTTP adapter example in the repository for a complete, working adapter that accepts a JSON service definition describing REST endpoints and calls them over HTTP. It stores per-service base URLs in adapterDomain, reads secrets for Authorization, and routes each invocation to the correct endpoint. See ServiceState for the shape of the snapshot the host delivers to hydrateService, and AdapterModule for the full interface contract.
Last modified on June 24, 2026