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
- Generate a unique id (e.g. `randomUUID()`) for each new MCP client.
- Check existence first with the list/get API and update instead of create when the id already exists.
- 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
- Always generate ids with crypto.randomUUID() for new records.
- Never re-run seed scripts without resetting in-memory storage.
- Prefer upsert semantics (check-then-create/update) in setup code.
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
- Version with id ${input.id} already exists
- MCP client with id ${id} not found
- Version number ${input.versionNumber} already exists for MCP
- MCP server with id ${mcpServer.id} already exists
- EXPERIMENT_ID_CONFLICT
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/6106439789058541.
Report an issue: GitHub.