mastra-ai/mastra · error

MCP client with id ${mcpClient.id} already exists

Error message

MCP client with id ${mcpClient.id} already exists

What it means

The in-memory MCP clients storage domain throws this from `create` when a client record with the same id is already stored in the `mcpClients` map. It enforces id uniqueness for MCP client configs. The library refuses to silently overwrite an existing configuration.

Source

Thrown at packages/core/src/storage/domains/mcp-clients/inmemory.ts:49

  async dangerouslyClearAll(): Promise<void> {
    this.db.mcpClients.clear();
    this.db.mcpClientVersions.clear();
  }

  // ==========================================================================
  // MCP Client CRUD Methods
  // ==========================================================================

  async getById(id: string): Promise<StorageMCPClientType | null> {
    const config = this.db.mcpClients.get(id);
    return config ? this.deepCopyConfig(config) : null;
  }

  async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {
    const { mcpClient } = input;

    if (this.db.mcpClients.has(mcpClient.id)) {
      throw new Error(`MCP client with id ${mcpClient.id} already exists`);
    }

    const now = new Date();
    const newConfig: StorageMCPClientType = {
      id: mcpClient.id,
      status: 'draft',
      activeVersionId: undefined,
      authorId: mcpClient.authorId,
      metadata: mcpClient.metadata,
      createdAt: now,
      updatedAt: now,
    };

    this.db.mcpClients.set(mcpClient.id, newConfig);

    // Extract config fields from the flat input (everything except record fields)
    const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Generate a unique id (e.g. `randomUUID()`) for each new MCP client.
  2. Check existence first with the list/get API and update instead of create when the id already exists.
  3. Use a fresh in-memory storage instance per test/run if repeated seeding is intended.

Example fix

// before
await mcpClients.create({ mcpClient: { id: 'my-client', ...cfg } });
// after
const id = crypto.randomUUID();
await mcpClients.create({ mcpClient: { id, ...cfg } });
Defensive patterns

Strategy: validation

Validate before calling

const existing = await mcpClients.list({ perPage: false });
if (existing.results.some(c => c.id === mcpClient.id)) {
  throw new Error(`Refusing to create: MCP client ${mcpClient.id} already exists`);
}

Try / catch

try {
  await mcpClients.create({ mcpClient });
} catch (err) {
  if (err instanceof Error && /already exists/.test(err.message)) return; // idempotent
  throw err;
}

Prevention

When it happens

Trigger: Calling `storage.mcpClients.create({ mcpClient })` where `mcp.db.mcpClients.has(mcpClient.id)` is true — i.e., a prior create (or seedAgent seeding) already inserted that exact id.

Common situations: Re-running a seeding/setup script without clearing in-memory storage; generating ids from a fixed string instead of a UUID; retry logic that re-invokes create after a partial success.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/6106439789058541. Report an issue: GitHub.