thedotmack/claude-mem · error · ServerClientError

missing_api_key

missing_api_key

Error message

${toolName}: ${resolution.reason}

What it means

requireServerForObservationTool throws this ServerClientError (code 'missing_api_key') when the runtime resolves to 'server' mode but resolution.available is false — resolution.reason explains why, almost always that the required server API key (or equivalent credential/server URL) is absent. It means the runtime selection succeeded but the tool cannot authenticate to the claude-mem server.

Solutions

  1. Read `${toolName}: ${resolution.reason}` in the message — it names the exact missing/misconfigured item.
  2. Create an API key with `claude-mem server api-key create` and export it in the MCP server's environment.
  3. Confirm the server endpoint/URL configuration is present alongside the key.
  4. Restart the MCP server after setting the credentials so the context is re-resolved.

Example fix

// before
CLAUDE_MEM_RUNTIME=server
// after
CLAUDE_MEM_RUNTIME=server
CLAUDE_MEM_SERVER_API_KEY=<key from `claude-mem server api-key create`>
CLAUDE_MEM_SERVER_URL=https://mem.example.com
Defensive patterns

Strategy: validation

Validate before calling

function hasServerCredentials(env: NodeJS.ProcessEnv = process.env): boolean {
  return (env.CLAUDE_MEM_RUNTIME ?? '').trim() === 'server'
    && Boolean((env.CLAUDE_MEM_SERVER_API_KEY ?? '').trim());
}

Try / catch

try {
  ctx = requireServerForObservationTool('observation_add');
} catch (err) {
  if (err instanceof ServerClientError && err.code === 'missing_api_key') {
    // surface remediation: run `claude-mem server api-key create` and export the key
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling a server-only observation tool while CLAUDE_MEM_RUNTIME=server is set but the server API key / credentials / endpoint configuration is missing or unusable, making resolveServerToolContext() return { available: false, reason }.

Common situations: Operator flipped CLAUDE_MEM_RUNTIME=server but never ran `claude-mem server api-key create` or didn't export the key env var; key var set in the wrong process scope; server URL misconfigured so the client can't build a valid request.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/efe43ab24351d8ab. Report an issue: GitHub.

Appendix: source

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

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) {
      const err = error instanceof Error ? error : new Error(String(error));
      logger.warn('SYSTEM', `${toolName} failed`, undefined, err);
      return formatToolError(error);
    }
  };
}

View on GitHub (pinned to d8bc9755e7)