thedotmack/claude-mem · error · ServerClientError

transport

transport

Error message

${toolName} requires CLAUDE_MEM_RUNTIME=server. Current runtime is "worker"; use the existing search/timeline/get_observations tools for worker-mode memory access.

What it means

Thrown by requireServerForObservationTool() when selectRuntime() returns a runtime other than 'server' (i.e. the install is in 'worker' runtime). The observation_* server-backed tools (observation_add, observation_record_event, observation_search, observation_context, observation_generation_status) only exist on the server /v1 surface, so they refuse to run against the worker. The error tells the caller which worker-mode equivalents to use instead.

Source

Thrown at src/servers/mcp-server.ts:206

      text: `Tool error: ${error instanceof Error ? error.message : String(error)}`,
    }],
    isError: true as const,
  };
}

function formatJsonResult(payload: unknown): { content: Array<{ type: 'text'; text: string }> } {
  return {
    content: [{
      type: 'text' as const,
      text: JSON.stringify(payload, null, 2),
    }],
  };
}

function requireServerForObservationTool(toolName: string): ServerAvailable {
  const resolution = resolveServerToolContext();
  if (!resolution) {
    throw new ServerClientError(
      'transport',
      `${toolName} requires CLAUDE_MEM_RUNTIME=server. Current runtime is "worker"; use the existing search/timeline/get_observations tools for worker-mode memory access.`,
    );
  }
  if (!resolution.available) {
    throw new ServerClientError('missing_api_key', `${toolName}: ${resolution.reason}`);
  }
  return resolution;
}

function wrapHandler<Args>(
  toolName: string,
  execute: (args: Args) => Promise<{ content: Array<{ type: 'text'; text: string }> }>,
): (args: Args) => Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> {
  return async (args: Args) => {
    try {
      return await execute(args);
    } catch (error) {

View on GitHub (pinned to d768ba3643)

Solutions

  1. Set the runtime to server: put CLAUDE_MEM_RUNTIME=server in your settings/env, then restart the MCP server (runtime is re-resolved per call, so no rebuild needed).
  2. If you cannot run the server runtime, stop calling the observation_* tools and use the worker-mode equivalents the message names: search, timeline, get_observations.
  3. Verify the switch took effect by checking selectRuntime()'s return or the debug log line from resolveServerToolContext().

Example fix

// before
// settings: { "runtime": "worker" }
// → observation_add throws 'requires CLAUDE_MEM_RUNTIME=server'

// after
// settings.json
{ "runtime": "server", "serverBaseUrl": "https://...", "apiKey": "cmem_..." }
// or env
export CLAUDE_MEM_RUNTIME=server
Defensive patterns

Strategy: validation

Validate before calling

// Resolve runtime before calling observation_* tools.
import { selectRuntime } from '<runtime-module>';
if (selectRuntime() !== 'server') {
  // do not call observation_*; use search/timeline/get_observations instead
}

Type guard

function isServerRuntime(): boolean {
  // mirrors resolveServerToolContext()'s null branch
  try { return selectRuntime() === 'server'; } catch { return false; }
}

Try / catch

try {
  await tools.observation_add({ content });
} catch (e) {
  if (e instanceof ServerClientError && e.kind === 'transport' && /requires CLAUDE_MEM_RUNTIME=server/.test(e.message)) {
    // wrong runtime — fall back to worker-mode tools
    await tools.search({ query: content });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling any observation_* tool while CLAUDE_MEM_RUNTIME=worker (or unset and resolving to worker). selectRuntime() returns 'worker', resolveServerToolContext() returns null, and the guard throws a ServerClientError of kind 'transport'.

Common situations: User upgraded to a version that introduced server-mode tools but never switched CLAUDE_MEM_RUNTIME to 'server' in settings/env; an MCP client auto-discovers advertised tools and calls one in a worker-only install; settings file has a typo in the runtime value so it falls back to worker.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/68c7930e49b855fb. Report an issue: GitHub.