From 1389443b217778b0903be7f84c4c6f0686b462be Mon Sep 17 00:00:00 2001 From: brojd Date: Mon, 9 Mar 2026 21:59:33 +0100 Subject: [PATCH 1/5] chore: rename internal_mcp_catalog.name to slug; introduce internal_mcp_catalog.display_name; handle duplicated names --- docs/openapi.json | 69 +- .../agents/subagents/policy-configuration.ts | 2 +- .../backend/src/archestra-mcp-server.test.ts | 9 +- platform/backend/src/archestra-mcp-server.ts | 2 +- .../backend/src/clients/mcp-client.test.ts | 44 +- platform/backend/src/clients/mcp-client.ts | 32 +- .../migrations/0174_curved_absorbing_man.sql | 22 + .../migrations/meta/0174_snapshot.json | 7623 +++++++++++++++++ .../database/migrations/meta/_journal.json | 7 + .../database/schemas/internal-mcp-catalog.ts | 3 +- platform/backend/src/database/seed.ts | 28 +- .../backend/src/models/agent-tool.test.ts | 10 +- platform/backend/src/models/agent.test.ts | 3 +- .../src/models/internal-mcp-catalog.test.ts | 78 +- .../src/models/internal-mcp-catalog.ts | 31 +- .../src/models/mcp-catalog-team.test.ts | 25 +- .../models/mcp-server-installation-request.ts | 9 +- .../backend/src/models/mcp-server.test.ts | 9 +- platform/backend/src/models/mcp-server.ts | 4 +- .../models/tool-archestra-assignment.test.ts | 3 +- platform/backend/src/models/tool.test.ts | 39 +- platform/backend/src/models/tool.ts | 9 +- .../routes/internal-mcp-catalog.env.test.ts | 27 +- .../src/routes/internal-mcp-catalog.ts | 39 +- platform/backend/src/routes/mcp-server.ts | 4 +- platform/backend/src/routes/oauth.ts | 6 +- .../src/services/mcp-reinstall.test.ts | 62 +- .../backend/src/services/mcp-reinstall.ts | 16 +- platform/backend/src/test/fixtures.ts | 9 +- platform/backend/src/types/mcp-catalog.ts | 6 +- platform/backend/src/types/mcp-server.ts | 2 +- platform/backend/src/types/tool.ts | 2 +- .../tests/api/built-in-agents.spec.ts | 10 +- .../tests/api/custom-yaml-restart.spec.ts | 3 +- platform/e2e-tests/tests/api/fixtures.ts | 3 +- .../tests/api/image-pull-secrets.spec.ts | 3 +- .../tests/api/mcp-catalog-labels.spec.ts | 27 +- .../api/mcp-gateway-auth-at-call-time.spec.ts | 3 +- .../mcp-gateway-jwt-propagation.ee.spec.ts | 29 +- .../e2e-tests/tests/api/mcp-gateway.spec.ts | 2 +- .../tests/api/oauth-self-hosted.spec.ts | 9 +- .../e2e-tests/tests/api/orchestrator.spec.ts | 8 +- .../tests/api/ssrf-protection.spec.ts | 3 +- platform/e2e-tests/utils.ts | 6 +- .../src/app/llm/(costs)/limits/page.tsx | 28 +- .../frontend/src/app/mcp/logs/page.client.tsx | 4 +- .../registry/_parts/InternalMCPCatalog.tsx | 39 +- .../registry/_parts/archestra-catalog-tab.tsx | 2 +- .../registry/_parts/delete-catalog-dialog.tsx | 4 +- .../_parts/local-server-install-dialog.tsx | 2 +- .../registry/_parts/mcp-catalog-form.utils.ts | 11 +- .../mcp/registry/_parts/mcp-server-card.tsx | 18 +- .../_parts/mcp-server-settings-dialog.tsx | 10 +- .../_parts/no-auth-install-dialog.tsx | 2 +- .../_parts/remote-server-install-dialog.tsx | 2 +- .../_parts/assigned-tools-table.tsx | 8 +- .../_parts/tool-details-dialog.tsx | 2 +- .../frontend/src/app/oauth-callback/page.tsx | 3 +- .../src/components/agent-tools-editor.tsx | 14 +- .../chat/initial-agent-selector.tsx | 14 +- .../components/chat/mcp-install-dialogs.tsx | 2 +- .../chat/tool-error-logs-button.tsx | 4 +- .../mcp-connection-instructions.tsx | 4 +- .../src/lib/mcp-install-orchestrator.hook.ts | 12 +- platform/frontend/src/lib/mcp-server.query.ts | 16 +- platform/shared/access-control.ts | 2 +- platform/shared/hey-api/clients/api/index.ts | 12 +- .../shared/hey-api/clients/api/sdk.gen.ts | 6 +- .../shared/hey-api/clients/api/types.gen.ts | 44 +- platform/shared/routes.ts | 2 +- 70 files changed, 8224 insertions(+), 383 deletions(-) create mode 100644 platform/backend/src/database/migrations/0174_curved_absorbing_man.sql create mode 100644 platform/backend/src/database/migrations/meta/0174_snapshot.json diff --git a/docs/openapi.json b/docs/openapi.json index cf34ff2c24..6f9d82e634 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -88159,7 +88159,10 @@ "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, - "name": { + "slug": { + "type": "string" + }, + "displayName": { "type": "string" }, "version": { @@ -88634,7 +88637,8 @@ }, "required": [ "id", - "name", + "slug", + "displayName", "version", "description", "instructions", @@ -88896,7 +88900,11 @@ "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, - "name": { + "slug": { + "type": "string", + "minLength": 1 + }, + "displayName": { "type": "string", "minLength": 1 }, @@ -89337,7 +89345,8 @@ } }, "required": [ - "name", + "slug", + "displayName", "serverType" ] } @@ -89358,7 +89367,10 @@ "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, - "name": { + "slug": { + "type": "string" + }, + "displayName": { "type": "string" }, "version": { @@ -89833,7 +89845,8 @@ }, "required": [ "id", - "name", + "slug", + "displayName", "version", "description", "instructions", @@ -90110,7 +90123,10 @@ "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, - "name": { + "slug": { + "type": "string" + }, + "displayName": { "type": "string" }, "version": { @@ -90585,7 +90601,8 @@ }, "required": [ "id", - "name", + "slug", + "displayName", "version", "description", "instructions", @@ -90841,7 +90858,11 @@ "schema": { "type": "object", "properties": { - "name": { + "slug": { + "type": "string", + "minLength": 1 + }, + "displayName": { "type": "string", "minLength": 1 }, @@ -91310,7 +91331,10 @@ "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, - "name": { + "slug": { + "type": "string" + }, + "displayName": { "type": "string" }, "version": { @@ -91785,7 +91809,8 @@ }, "required": [ "id", - "name", + "slug", + "displayName", "version", "description", "instructions", @@ -92578,13 +92603,13 @@ } } }, - "/api/internal_mcp_catalog/by-name/{name}": { + "/api/internal_mcp_catalog/by-slug/{slug}": { "delete": { - "operationId": "deleteInternalMcpCatalogItemByName", + "operationId": "deleteInternalMcpCatalogItemBySlug", "tags": [ "MCP Catalog" ], - "description": "Delete an Internal MCP catalog item by name", + "description": "Delete an Internal MCP catalog item by slug", "parameters": [ { "schema": { @@ -92592,7 +92617,7 @@ "minLength": 1 }, "in": "path", - "name": "name", + "name": "slug", "required": true } ], @@ -109023,7 +109048,7 @@ "nullable": true, "type": "string" }, - "catalogName": { + "catalogSlug": { "nullable": true, "type": "string" }, @@ -109511,7 +109536,7 @@ "nullable": true, "type": "string" }, - "catalogName": { + "catalogSlug": { "nullable": true, "type": "string" }, @@ -109915,7 +109940,7 @@ "nullable": true, "type": "string" }, - "catalogName": { + "catalogSlug": { "nullable": true, "type": "string" }, @@ -110603,7 +110628,7 @@ "nullable": true, "type": "string" }, - "catalogName": { + "catalogSlug": { "nullable": true, "type": "string" }, @@ -111865,7 +111890,7 @@ "nullable": true, "type": "string" }, - "catalogName": { + "catalogSlug": { "nullable": true, "type": "string" }, @@ -129971,13 +129996,13 @@ "id": { "type": "string" }, - "name": { + "slug": { "type": "string" } }, "required": [ "id", - "name" + "slug" ], "additionalProperties": false } diff --git a/platform/backend/src/agents/subagents/policy-configuration.ts b/platform/backend/src/agents/subagents/policy-configuration.ts index f3f609da8f..f1a1f1d7d6 100644 --- a/platform/backend/src/agents/subagents/policy-configuration.ts +++ b/platform/backend/src/agents/subagents/policy-configuration.ts @@ -103,7 +103,7 @@ export class PolicyConfigurationService { const catalog = await InternalMcpCatalogModel.findById(tool.catalogId, { expandSecrets: false, }); - mcpServerName = catalog?.name ?? null; + mcpServerName = catalog?.slug ?? null; } logger.debug( diff --git a/platform/backend/src/archestra-mcp-server.test.ts b/platform/backend/src/archestra-mcp-server.test.ts index ba76cf364c..a018688375 100644 --- a/platform/backend/src/archestra-mcp-server.test.ts +++ b/platform/backend/src/archestra-mcp-server.test.ts @@ -189,7 +189,8 @@ describe("executeArchestraTool", () => { makeInternalMcpCatalog, }) => { await makeInternalMcpCatalog({ - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", version: "1.0.0", description: "A test server", serverType: "remote", @@ -245,13 +246,15 @@ describe("executeArchestraTool", () => { makeInternalMcpCatalog, }) => { await makeInternalMcpCatalog({ - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", description: "A server for testing", serverType: "remote", }); await makeInternalMcpCatalog({ - name: "Other Server", + slug: "Other Server", + displayName: "Other Server", description: "A different server", serverType: "remote", }); diff --git a/platform/backend/src/archestra-mcp-server.ts b/platform/backend/src/archestra-mcp-server.ts index 88975f2aeb..fc090f3911 100644 --- a/platform/backend/src/archestra-mcp-server.ts +++ b/platform/backend/src/archestra-mcp-server.ts @@ -349,7 +349,7 @@ export async function executeArchestraTool( // Format the results const formattedResults = catalogItems .map((item) => { - let result = `**${item.name}**`; + let result = `**${item.slug}**`; if (item.version) result += ` (v${item.version})`; if (item.description) result += `\n ${item.description}`; result += `\n Type: ${item.serverType}`; diff --git a/platform/backend/src/clients/mcp-client.test.ts b/platform/backend/src/clients/mcp-client.test.ts index 0dde13d7eb..7b803afc01 100644 --- a/platform/backend/src/clients/mcp-client.test.ts +++ b/platform/backend/src/clients/mcp-client.test.ts @@ -93,7 +93,8 @@ describe("McpClient", () => { // Create catalog entry for the MCP server const catalogItem = await InternalMcpCatalogModel.create({ - name: "github-mcp-server", + slug: "github-mcp-server", + displayName: "github-mcp-server", serverType: "remote", serverUrl: "https://api.githubcopilot.com/mcp/", }); @@ -643,7 +644,8 @@ describe("McpClient", () => { // Create catalog entry for local streamable-http server const localCatalog = await InternalMcpCatalogModel.create({ - name: "local-streamable-http-server", + slug: "local-streamable-http-server", + displayName: "local-streamable-http-server", serverType: "local", localConfig: { command: "npx", @@ -932,8 +934,8 @@ describe("McpClient", () => { } }); - test("strips catalogName prefix when mcpServerName includes userId suffix (Issue #1179)", async () => { - // Create tool with catalogName prefix (how local server tools are actually created) + test("strips catalogSlug prefix when mcpServerName includes userId suffix (Issue #1179)", async () => { + // Create tool with catalogSlug prefix (how local server tools are actually created) const tool = await ToolModel.createToolIfNotExists({ name: "local-streamable-http-server__prefix_test_tool", description: "Tool for testing prefix stripping fallback", @@ -963,7 +965,7 @@ describe("McpClient", () => { const result = await mcpClient.executeToolCall(toolCall, agentId); - // Verify the tool was called with just the tool name (stripped using catalogName) + // Verify the tool was called with just the tool name (stripped using catalogSlug) expect(mockCallTool).toHaveBeenCalledWith({ name: "prefix_test_tool", arguments: {}, @@ -976,10 +978,11 @@ describe("McpClient", () => { }); }); - test("falls back to stripping mcpServerName when catalogName prefix is missing", async () => { + test("falls back to stripping mcpServerName when catalogSlug prefix is missing", async () => { // Create catalog with different name to ensure catalog prefix doesn't match const otherCatalog = await InternalMcpCatalogModel.create({ - name: "other-catalog", + slug: "other-catalog", + displayName: "other-catalog", serverType: "local", }); @@ -1101,7 +1104,8 @@ describe("McpClient", () => { // Create a separate catalog + tool for dynamic credential testing const dynCatalog = await InternalMcpCatalogModel.create({ - name: "jira-mcp-server", + slug: "jira-mcp-server", + displayName: "jira-mcp-server", serverType: "remote", serverUrl: "https://mcp.atlassian.com/v1/mcp", }); @@ -1169,7 +1173,8 @@ describe("McpClient", () => { // Create catalog + tool const dynCatalog = await InternalMcpCatalogModel.create({ - name: "jira-team-server", + slug: "jira-team-server", + displayName: "jira-team-server", serverType: "remote", serverUrl: "https://mcp.atlassian.com/v1/mcp", }); @@ -1230,7 +1235,8 @@ describe("McpClient", () => { // Create catalog + server owned by serverOwner const dynCatalog = await InternalMcpCatalogModel.create({ - name: "slack-mcp-server", + slug: "slack-mcp-server", + displayName: "slack-mcp-server", serverType: "remote", serverUrl: "https://mcp.slack.com/v1/mcp", }); @@ -1303,7 +1309,8 @@ describe("McpClient", () => { // Create an OAuth-enabled catalog const oauthCatalog = await InternalMcpCatalogModel.create({ - name: "github-oauth-server", + slug: "github-oauth-server", + displayName: "github-oauth-server", serverType: "remote", serverUrl: "https://api.githubcopilot.com/mcp/", oauthConfig: { @@ -1383,7 +1390,8 @@ describe("McpClient", () => { }); const oauthCatalog = await InternalMcpCatalogModel.create({ - name: "github-http401-server", + slug: "github-http401-server", + displayName: "github-http401-server", serverType: "remote", serverUrl: "https://api.githubcopilot.com/mcp/", oauthConfig: { @@ -1461,7 +1469,8 @@ describe("McpClient", () => { // Create catalog WITHOUT oauthConfig (PAT-based auth like GitHub) const nonOauthCatalog = await InternalMcpCatalogModel.create({ - name: "private-api-server", + slug: "private-api-server", + displayName: "private-api-server", serverType: "remote", serverUrl: "https://private-api.example.com/mcp/", }); @@ -1528,7 +1537,8 @@ describe("McpClient", () => { // Non-OAuth catalog (like GitHub with PAT) const catalog = await InternalMcpCatalogModel.create({ - name: "github-pat-server", + slug: "github-pat-server", + displayName: "github-pat-server", serverType: "remote", serverUrl: "https://api.githubcopilot.com/mcp/", }); @@ -1606,7 +1616,8 @@ describe("McpClient", () => { }); const oauthCatalog = await InternalMcpCatalogModel.create({ - name: "github-team-oauth-server", + slug: "github-team-oauth-server", + displayName: "github-team-oauth-server", serverType: "remote", serverUrl: "https://api.githubcopilot.com/mcp/", oauthConfig: { @@ -1683,7 +1694,8 @@ describe("McpClient", () => { }); const localCatalog = await InternalMcpCatalogModel.create({ - name: "stale-session-server", + slug: "stale-session-server", + displayName: "stale-session-server", serverType: "local", localConfig: { dockerImage: "mcr.microsoft.com/playwright/mcp", diff --git a/platform/backend/src/clients/mcp-client.ts b/platform/backend/src/clients/mcp-client.ts index 12c831db0f..5e0a430125 100644 --- a/platform/backend/src/clients/mcp-client.ts +++ b/platform/backend/src/clients/mcp-client.ts @@ -58,7 +58,7 @@ type McpToolWithServerMetadata = { executionSourceMcpServerId: string | null; useDynamicTeamCredential: boolean; catalogId: string | null; - catalogName: string | null; + catalogSlug: string | null; }; /** @@ -283,15 +283,15 @@ class McpClient { const client = await this.getOrCreateClient(connectionKey, transport); // Determine the actual tool name by stripping the server/catalog prefix. - // We prioritize the `catalogName` prefix, which is standard for local MCP servers. + // We prioritize the `catalogSlug` prefix, which is standard for local MCP servers. // If the tool name doesn't match the catalog prefix, we fall back to the resolved `mcpServerName`. let targetToolName = this.stripServerPrefix( toolCall.name, - tool.catalogName || "", + tool.catalogSlug || "", ); if (targetToolName === toolCall.name) { - // No prefix match with catalogName; attempt to strip using mcpServerName instead. + // No prefix match with catalogSlug; attempt to strip using mcpServerName instead. targetToolName = this.stripServerPrefix(toolCall.name, mcpServerName); } @@ -442,7 +442,7 @@ class McpClient { targetMcpServerId, tokenAuth, toolCatalogId: tool.catalogId, - toolCatalogName: tool.catalogName, + toolCatalogSlug: tool.catalogSlug, executeRetry: (getTransport, secrets) => executeToolCall(getTransport, secrets, true), }); @@ -455,7 +455,7 @@ class McpClient { // For auth errors, return an actionable message with re-auth URL if (isAuthError && tool.catalogId) { - const catalogDisplayName = tool.catalogName || tool.catalogId; + const catalogDisplayName = tool.catalogSlug || tool.catalogId; // Credentials exist but failed → "expired/invalid" message with manage link if (targetMcpServerId) { return await this.createErrorResult( @@ -706,7 +706,7 @@ class McpClient { toolCall, agentId, "Tool is missing catalogId", - tool.catalogName || "unknown", + tool.catalogSlug || "unknown", ), }; } @@ -719,7 +719,7 @@ class McpClient { toolCall, agentId, `No catalog item found for tool catalog ID ${tool.catalogId}`, - tool.catalogName || "unknown", + tool.catalogSlug || "unknown", ), }; } @@ -817,7 +817,7 @@ class McpClient { | { targetMcpServerId: string; mcpServerName: string } | { error: CommonToolResult } > { - const fallbackName = tool.catalogName || "unknown"; + const fallbackName = tool.catalogSlug || "unknown"; logger.info( { toolName: toolCall.name, @@ -1015,7 +1015,7 @@ class McpClient { } // No server found - return an actionable error with install link - const catalogDisplayName = tool.catalogName || tool.catalogId; + const catalogDisplayName = tool.catalogSlug || tool.catalogId; return { error: await this.createErrorResult( toolCall, @@ -1357,7 +1357,7 @@ class McpClient { targetMcpServerId: string; tokenAuth?: TokenAuthContext; toolCatalogId: string | null; - toolCatalogName: string | null; + toolCatalogSlug: string | null; executeRetry: ( getTransport: () => Promise, secrets: Record, @@ -1374,7 +1374,7 @@ class McpClient { targetMcpServerId, tokenAuth, toolCatalogId, - toolCatalogName, + toolCatalogSlug, executeRetry, } = params; @@ -1456,7 +1456,7 @@ class McpClient { isAuthRelatedError(retryErrorMsg); if (isRetryAuthError && toolCatalogId) { - const catalogDisplayName = toolCatalogName || toolCatalogId; + const catalogDisplayName = toolCatalogSlug || toolCatalogId; return await this.createErrorResult( toolCall, agentId, @@ -1661,7 +1661,7 @@ class McpClient { if (attempt < maxRetries) { logger.warn( { attempt, maxRetries, err: error }, - `Failed to connect to MCP server ${catalogItem.name} (attempt ${attempt}/${maxRetries}). Retrying in ${retryDelayMs}ms...`, + `Failed to connect to MCP server ${catalogItem.slug} (attempt ${attempt}/${maxRetries}). Retrying in ${retryDelayMs}ms...`, ); await new Promise((resolve) => setTimeout(resolve, retryDelayMs)); continue; @@ -1669,14 +1669,14 @@ class McpClient { // Last attempt failed, throw error throw new Error( - `Failed to connect to MCP server ${catalogItem.name}: ${lastError.message}`, + `Failed to connect to MCP server ${catalogItem.slug}: ${lastError.message}`, ); } } // Should never reach here, but TypeScript needs it throw new Error( - `Failed to connect to MCP server ${catalogItem.name}: ${ + `Failed to connect to MCP server ${catalogItem.slug}: ${ lastError?.message || "Unknown error" }`, ); diff --git a/platform/backend/src/database/migrations/0174_curved_absorbing_man.sql b/platform/backend/src/database/migrations/0174_curved_absorbing_man.sql new file mode 100644 index 0000000000..2e1f31ea93 --- /dev/null +++ b/platform/backend/src/database/migrations/0174_curved_absorbing_man.sql @@ -0,0 +1,22 @@ +-- Step 1: Rename name → slug +ALTER TABLE "internal_mcp_catalog" RENAME COLUMN "name" TO "slug";--> statement-breakpoint + +-- Step 2: Add display_name column as nullable first, then populate, then set NOT NULL +ALTER TABLE "internal_mcp_catalog" ADD COLUMN "display_name" text;--> statement-breakpoint +UPDATE "internal_mcp_catalog" SET "display_name" = "slug";--> statement-breakpoint +ALTER TABLE "internal_mcp_catalog" ALTER COLUMN "display_name" SET NOT NULL;--> statement-breakpoint + +-- Step 3: Deduplicate slugs before adding unique constraint. +-- For each group of rows sharing the same slug, keep the oldest row's slug unchanged +-- and append a short ID suffix only to the newer duplicates. +-- Rows with unique slugs are not affected. +UPDATE "internal_mcp_catalog" SET "slug" = "slug" || '-' || LEFT("id"::text, 4) +WHERE "id" IN ( + SELECT "id" FROM ( + SELECT "id", ROW_NUMBER() OVER (PARTITION BY "slug" ORDER BY "created_at" ASC) AS rn + FROM "internal_mcp_catalog" + ) ranked WHERE rn > 1 +);--> statement-breakpoint + +-- Step 4: Now safe to add unique constraint +ALTER TABLE "internal_mcp_catalog" ADD CONSTRAINT "internal_mcp_catalog_slug_unique" UNIQUE("slug"); diff --git a/platform/backend/src/database/migrations/meta/0174_snapshot.json b/platform/backend/src/database/migrations/meta/0174_snapshot.json new file mode 100644 index 0000000000..8429774617 --- /dev/null +++ b/platform/backend/src/database/migrations/meta/0174_snapshot.json @@ -0,0 +1,7623 @@ +{ + "id": "2ec8d7ca-a162-4992-ad80-35ee21eafbc7", + "prevId": "d4f52644-de03-47f3-9b64-be9b330195c5", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_connector_assignment": { + "name": "agent_connector_assignment", + "schema": "", + "columns": { + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "connector_id": { + "name": "connector_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "agent_connector_assignment_agent_idx": { + "name": "agent_connector_assignment_agent_idx", + "columns": [ + { + "expression": "agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "agent_connector_assignment_connector_idx": { + "name": "agent_connector_assignment_connector_idx", + "columns": [ + { + "expression": "connector_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_connector_assignment_agent_id_agents_id_fk": { + "name": "agent_connector_assignment_agent_id_agents_id_fk", + "tableFrom": "agent_connector_assignment", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_connector_assignment_connector_id_knowledge_base_connectors_id_fk": { + "name": "agent_connector_assignment_connector_id_knowledge_base_connectors_id_fk", + "tableFrom": "agent_connector_assignment", + "tableTo": "knowledge_base_connectors", + "columnsFrom": [ + "connector_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "agent_connector_assignment_agent_id_connector_id_pk": { + "name": "agent_connector_assignment_agent_id_connector_id_pk", + "columns": [ + "agent_id", + "connector_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_knowledge_base": { + "name": "agent_knowledge_base", + "schema": "", + "columns": { + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "knowledge_base_id": { + "name": "knowledge_base_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "agent_knowledge_base_agent_idx": { + "name": "agent_knowledge_base_agent_idx", + "columns": [ + { + "expression": "agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "agent_knowledge_base_kb_idx": { + "name": "agent_knowledge_base_kb_idx", + "columns": [ + { + "expression": "knowledge_base_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_knowledge_base_agent_id_agents_id_fk": { + "name": "agent_knowledge_base_agent_id_agents_id_fk", + "tableFrom": "agent_knowledge_base", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_knowledge_base_knowledge_base_id_knowledge_bases_id_fk": { + "name": "agent_knowledge_base_knowledge_base_id_knowledge_bases_id_fk", + "tableFrom": "agent_knowledge_base", + "tableTo": "knowledge_bases", + "columnsFrom": [ + "knowledge_base_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "agent_knowledge_base_agent_id_knowledge_base_id_pk": { + "name": "agent_knowledge_base_agent_id_knowledge_base_id_pk", + "columns": [ + "agent_id", + "knowledge_base_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_labels": { + "name": "agent_labels", + "schema": "", + "columns": { + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key_id": { + "name": "key_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value_id": { + "name": "value_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "agent_labels_agent_id_agents_id_fk": { + "name": "agent_labels_agent_id_agents_id_fk", + "tableFrom": "agent_labels", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_labels_key_id_label_keys_id_fk": { + "name": "agent_labels_key_id_label_keys_id_fk", + "tableFrom": "agent_labels", + "tableTo": "label_keys", + "columnsFrom": [ + "key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_labels_value_id_label_values_id_fk": { + "name": "agent_labels_value_id_label_values_id_fk", + "tableFrom": "agent_labels", + "tableTo": "label_values", + "columnsFrom": [ + "value_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "agent_labels_agent_id_key_id_pk": { + "name": "agent_labels_agent_id_key_id_pk", + "columns": [ + "agent_id", + "key_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_team": { + "name": "agent_team", + "schema": "", + "columns": { + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "agent_team_agent_id_agents_id_fk": { + "name": "agent_team_agent_id_agents_id_fk", + "tableFrom": "agent_team", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_team_team_id_team_id_fk": { + "name": "agent_team_team_id_team_id_fk", + "tableFrom": "agent_team", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "agent_team_agent_id_team_id_pk": { + "name": "agent_team_agent_id_team_id_pk", + "columns": [ + "agent_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_tools": { + "name": "agent_tools", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tool_id": { + "name": "tool_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "response_modifier_template": { + "name": "response_modifier_template", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_source_mcp_server_id": { + "name": "credential_source_mcp_server_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "execution_source_mcp_server_id": { + "name": "execution_source_mcp_server_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "use_dynamic_team_credential": { + "name": "use_dynamic_team_credential", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "agent_tools_agent_id_agents_id_fk": { + "name": "agent_tools_agent_id_agents_id_fk", + "tableFrom": "agent_tools", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_tools_tool_id_tools_id_fk": { + "name": "agent_tools_tool_id_tools_id_fk", + "tableFrom": "agent_tools", + "tableTo": "tools", + "columnsFrom": [ + "tool_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_tools_credential_source_mcp_server_id_mcp_server_id_fk": { + "name": "agent_tools_credential_source_mcp_server_id_mcp_server_id_fk", + "tableFrom": "agent_tools", + "tableTo": "mcp_server", + "columnsFrom": [ + "credential_source_mcp_server_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "agent_tools_execution_source_mcp_server_id_mcp_server_id_fk": { + "name": "agent_tools_execution_source_mcp_server_id_mcp_server_id_fk", + "tableFrom": "agent_tools", + "tableTo": "mcp_server", + "columnsFrom": [ + "execution_source_mcp_server_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "agent_tools_agent_id_tool_id_unique": { + "name": "agent_tools_agent_id_tool_id_unique", + "nullsNotDistinct": false, + "columns": [ + "agent_id", + "tool_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agents": { + "name": "agents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "agent_scope", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'personal'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_demo": { + "name": "is_demo", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "consider_context_untrusted": { + "name": "consider_context_untrusted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "agent_type": { + "name": "agent_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'mcp_gateway'" + }, + "system_prompt": { + "name": "system_prompt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_prompt": { + "name": "user_prompt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prompt_version": { + "name": "prompt_version", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 1 + }, + "prompt_history": { + "name": "prompt_history", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "incoming_email_enabled": { + "name": "incoming_email_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "incoming_email_security_mode": { + "name": "incoming_email_security_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'private'" + }, + "incoming_email_allowed_domain": { + "name": "incoming_email_allowed_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "llm_api_key_id": { + "name": "llm_api_key_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "llm_model": { + "name": "llm_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "identity_provider_id": { + "name": "identity_provider_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "built_in_agent_config": { + "name": "built_in_agent_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "built_in": { + "name": "built_in", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "generated": { + "as": "\"agents\".\"built_in_agent_config\" IS NOT NULL", + "type": "stored" + } + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "agents_organization_id_idx": { + "name": "agents_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "agents_agent_type_idx": { + "name": "agents_agent_type_idx", + "columns": [ + { + "expression": "agent_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "agents_identity_provider_id_idx": { + "name": "agents_identity_provider_id_idx", + "columns": [ + { + "expression": "identity_provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "agents_author_id_idx": { + "name": "agents_author_id_idx", + "columns": [ + { + "expression": "author_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "agents_scope_idx": { + "name": "agents_scope_idx", + "columns": [ + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agents_author_id_user_id_fk": { + "name": "agents_author_id_user_id_fk", + "tableFrom": "agents", + "tableTo": "user", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "agents_llm_api_key_id_chat_api_keys_id_fk": { + "name": "agents_llm_api_key_id_chat_api_keys_id_fk", + "tableFrom": "agents", + "tableTo": "chat_api_keys", + "columnsFrom": [ + "llm_api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "agents_identity_provider_id_identity_provider_id_fk": { + "name": "agents_identity_provider_id_identity_provider_id_fk", + "tableFrom": "agents", + "tableTo": "identity_provider", + "columnsFrom": [ + "identity_provider_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.api_key_models": { + "name": "api_key_models", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "api_key_id": { + "name": "api_key_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "model_id": { + "name": "model_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "is_fastest": { + "name": "is_fastest", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_best": { + "name": "is_best", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "api_key_models_api_key_id_idx": { + "name": "api_key_models_api_key_id_idx", + "columns": [ + { + "expression": "api_key_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "api_key_models_model_id_idx": { + "name": "api_key_models_model_id_idx", + "columns": [ + { + "expression": "model_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_key_models_api_key_id_chat_api_keys_id_fk": { + "name": "api_key_models_api_key_id_chat_api_keys_id_fk", + "tableFrom": "api_key_models", + "tableTo": "chat_api_keys", + "columnsFrom": [ + "api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "api_key_models_model_id_models_id_fk": { + "name": "api_key_models_model_id_models_id_fk", + "tableFrom": "api_key_models", + "tableTo": "models", + "columnsFrom": [ + "model_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_key_models_unique": { + "name": "api_key_models_unique", + "nullsNotDistinct": false, + "columns": [ + "api_key_id", + "model_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "apikey_user_id_user_id_fk": { + "name": "apikey_user_id_user_id_fk", + "tableFrom": "apikey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.browser_tab_states": { + "name": "browser_tab_states", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "isolation_key": { + "name": "isolation_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tab_index": { + "name": "tab_index", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "browser_tab_states_agent_user_isolation_idx": { + "name": "browser_tab_states_agent_user_isolation_idx", + "columns": [ + { + "expression": "agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "isolation_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "browser_tab_states_user_id_idx": { + "name": "browser_tab_states_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "browser_tab_states_agent_id_agents_id_fk": { + "name": "browser_tab_states_agent_id_agents_id_fk", + "tableFrom": "browser_tab_states", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "browser_tab_states_user_id_user_id_fk": { + "name": "browser_tab_states_user_id_user_id_fk", + "tableFrom": "browser_tab_states", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chat_api_keys": { + "name": "chat_api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "secret_id": { + "name": "secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'personal'" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_system": { + "name": "is_system", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "chat_api_keys_organization_id_idx": { + "name": "chat_api_keys_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "chat_api_keys_org_provider_idx": { + "name": "chat_api_keys_org_provider_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "chat_api_keys_system_unique": { + "name": "chat_api_keys_system_unique", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"chat_api_keys\".\"is_system\" = true", + "concurrently": false, + "method": "btree", + "with": {} + }, + "chat_api_keys_primary_personal_unique": { + "name": "chat_api_keys_primary_personal_unique", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"chat_api_keys\".\"is_primary\" = true AND \"chat_api_keys\".\"scope\" = 'personal'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "chat_api_keys_primary_team_unique": { + "name": "chat_api_keys_primary_team_unique", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"chat_api_keys\".\"is_primary\" = true AND \"chat_api_keys\".\"scope\" = 'team'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "chat_api_keys_primary_org_wide_unique": { + "name": "chat_api_keys_primary_org_wide_unique", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"chat_api_keys\".\"is_primary\" = true AND \"chat_api_keys\".\"scope\" = 'org_wide'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "chat_api_keys_secret_id_secret_id_fk": { + "name": "chat_api_keys_secret_id_secret_id_fk", + "tableFrom": "chat_api_keys", + "tableTo": "secret", + "columnsFrom": [ + "secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "chat_api_keys_user_id_user_id_fk": { + "name": "chat_api_keys_user_id_user_id_fk", + "tableFrom": "chat_api_keys", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "chat_api_keys_team_id_team_id_fk": { + "name": "chat_api_keys_team_id_team_id_fk", + "tableFrom": "chat_api_keys", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chatops_channel_binding": { + "name": "chatops_channel_binding", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "channel_id": { + "name": "channel_id", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "channel_name": { + "name": "channel_name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "workspace_name": { + "name": "workspace_name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "is_dm": { + "name": "is_dm", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "dm_owner_email": { + "name": "dm_owner_email", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "chatops_channel_binding_provider_channel_workspace_idx": { + "name": "chatops_channel_binding_provider_channel_workspace_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "chatops_channel_binding_organization_id_idx": { + "name": "chatops_channel_binding_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "chatops_channel_binding_agent_id_idx": { + "name": "chatops_channel_binding_agent_id_idx", + "columns": [ + { + "expression": "agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "chatops_channel_binding_agent_id_agents_id_fk": { + "name": "chatops_channel_binding_agent_id_agents_id_fk", + "tableFrom": "chatops_channel_binding", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chatops_processed_message": { + "name": "chatops_processed_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "message_id": { + "name": "message_id", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "chatops_processed_message_processed_at_idx": { + "name": "chatops_processed_message_processed_at_idx", + "columns": [ + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "chatops_processed_message_message_id_unique": { + "name": "chatops_processed_message_message_id_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.connector_runs": { + "name": "connector_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "connector_id": { + "name": "connector_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "documents_processed": { + "name": "documents_processed", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "documents_ingested": { + "name": "documents_ingested", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "total_items": { + "name": "total_items", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_batches": { + "name": "total_batches", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "completed_batches": { + "name": "completed_batches", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logs": { + "name": "logs", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "checkpoint": { + "name": "checkpoint", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "connector_runs_connector_id_idx": { + "name": "connector_runs_connector_id_idx", + "columns": [ + { + "expression": "connector_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "connector_runs_connector_id_knowledge_base_connectors_id_fk": { + "name": "connector_runs_connector_id_knowledge_base_connectors_id_fk", + "tableFrom": "connector_runs", + "tableTo": "knowledge_base_connectors", + "columnsFrom": [ + "connector_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.conversation_enabled_tools": { + "name": "conversation_enabled_tools", + "schema": "", + "columns": { + "conversation_id": { + "name": "conversation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tool_id": { + "name": "tool_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "conversation_enabled_tools_conversation_id_conversations_id_fk": { + "name": "conversation_enabled_tools_conversation_id_conversations_id_fk", + "tableFrom": "conversation_enabled_tools", + "tableTo": "conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "conversation_enabled_tools_tool_id_tools_id_fk": { + "name": "conversation_enabled_tools_tool_id_tools_id_fk", + "tableFrom": "conversation_enabled_tools", + "tableTo": "tools", + "columnsFrom": [ + "tool_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "conversation_enabled_tools_conversation_id_tool_id_pk": { + "name": "conversation_enabled_tools_conversation_id_tool_id_pk", + "columns": [ + "conversation_id", + "tool_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.conversation_shares": { + "name": "conversation_shares", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "conversation_id": { + "name": "conversation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "conversation_share_visibility", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'organization'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "conversation_shares_conversation_id_conversations_id_fk": { + "name": "conversation_shares_conversation_id_conversations_id_fk", + "tableFrom": "conversation_shares", + "tableTo": "conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "conversation_shares_conversation_id_unique": { + "name": "conversation_shares_conversation_id_unique", + "nullsNotDistinct": false, + "columns": [ + "conversation_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.conversations": { + "name": "conversations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "chat_api_key_id": { + "name": "chat_api_key_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "selected_model": { + "name": "selected_model", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'gpt-4o'" + }, + "selected_provider": { + "name": "selected_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "has_custom_tool_selection": { + "name": "has_custom_tool_selection", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "todo_list": { + "name": "todo_list", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "artifact": { + "name": "artifact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pinned_at": { + "name": "pinned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "conversations_agent_id_agents_id_fk": { + "name": "conversations_agent_id_agents_id_fk", + "tableFrom": "conversations", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "conversations_chat_api_key_id_chat_api_keys_id_fk": { + "name": "conversations_chat_api_key_id_chat_api_keys_id_fk", + "tableFrom": "conversations", + "tableTo": "chat_api_keys", + "columnsFrom": [ + "chat_api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dual_llm_config": { + "name": "dual_llm_config", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "main_agent_prompt": { + "name": "main_agent_prompt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "quarantined_agent_prompt": { + "name": "quarantined_agent_prompt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "summary_prompt": { + "name": "summary_prompt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "max_rounds": { + "name": "max_rounds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dual_llm_results": { + "name": "dual_llm_results", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tool_call_id": { + "name": "tool_call_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "conversations": { + "name": "conversations", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "result": { + "name": "result", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dual_llm_results_agent_id_idx": { + "name": "dual_llm_results_agent_id_idx", + "columns": [ + { + "expression": "agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dual_llm_results_agent_id_agents_id_fk": { + "name": "dual_llm_results_agent_id_agents_id_fk", + "tableFrom": "dual_llm_results", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.identity_provider": { + "name": "identity_provider", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "issuer": { + "name": "issuer", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oidc_config": { + "name": "oidc_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "saml_config": { + "name": "saml_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "role_mapping": { + "name": "role_mapping", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "team_sync_config": { + "name": "team_sync_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_verified": { + "name": "domain_verified", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "identity_provider_user_id_user_id_fk": { + "name": "identity_provider_user_id_user_id_fk", + "tableFrom": "identity_provider", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "identity_provider_provider_id_unique": { + "name": "identity_provider_provider_id_unique", + "nullsNotDistinct": false, + "columns": [ + "provider_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.incoming_email_subscription": { + "name": "incoming_email_subscription", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "webhook_url": { + "name": "webhook_url", + "type": "varchar(1024)", + "primaryKey": false, + "notNull": true + }, + "client_state": { + "name": "client_state", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.interactions": { + "name": "interactions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "external_agent_id": { + "name": "external_agent_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "execution_id": { + "name": "execution_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "session_source": { + "name": "session_source", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "request": { + "name": "request", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "processed_request": { + "name": "processed_request", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "response": { + "name": "response", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "baseline_model": { + "name": "baseline_model", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "input_tokens": { + "name": "input_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "output_tokens": { + "name": "output_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "baseline_cost": { + "name": "baseline_cost", + "type": "numeric(13, 10)", + "primaryKey": false, + "notNull": false + }, + "cost": { + "name": "cost", + "type": "numeric(13, 10)", + "primaryKey": false, + "notNull": false + }, + "toon_tokens_before": { + "name": "toon_tokens_before", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "toon_tokens_after": { + "name": "toon_tokens_after", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "toon_cost_savings": { + "name": "toon_cost_savings", + "type": "numeric(13, 10)", + "primaryKey": false, + "notNull": false + }, + "toon_skip_reason": { + "name": "toon_skip_reason", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "interactions_agent_id_idx": { + "name": "interactions_agent_id_idx", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "interactions_external_agent_id_idx": { + "name": "interactions_external_agent_id_idx", + "columns": [ + { + "expression": "external_agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "interactions_execution_id_idx": { + "name": "interactions_execution_id_idx", + "columns": [ + { + "expression": "execution_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "interactions_user_id_idx": { + "name": "interactions_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "interactions_session_id_idx": { + "name": "interactions_session_id_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "interactions_created_at_idx": { + "name": "interactions_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "interactions_profile_created_at_idx": { + "name": "interactions_profile_created_at_idx", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "interactions_session_created_at_idx": { + "name": "interactions_session_created_at_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "interactions_profile_id_agents_id_fk": { + "name": "interactions_profile_id_agents_id_fk", + "tableFrom": "interactions", + "tableTo": "agents", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "interactions_user_id_user_id_fk": { + "name": "interactions_user_id_user_id_fk", + "tableFrom": "interactions", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.internal_mcp_catalog": { + "name": "internal_mcp_catalog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "instructions": { + "name": "instructions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "repository": { + "name": "repository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "installation_command": { + "name": "installation_command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requires_auth": { + "name": "requires_auth", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "auth_description": { + "name": "auth_description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_fields": { + "name": "auth_fields", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "server_type": { + "name": "server_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "server_url": { + "name": "server_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "docs_url": { + "name": "docs_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_secret_id": { + "name": "client_secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "local_config_secret_id": { + "name": "local_config_secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "local_config": { + "name": "local_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "deployment_spec_yaml": { + "name": "deployment_spec_yaml", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_config": { + "name": "user_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "oauth_config": { + "name": "oauth_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "author_id": { + "name": "author_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "mcp_catalog_scope", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'org'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "internal_mcp_catalog_organization_id_idx": { + "name": "internal_mcp_catalog_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "internal_mcp_catalog_author_id_idx": { + "name": "internal_mcp_catalog_author_id_idx", + "columns": [ + { + "expression": "author_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "internal_mcp_catalog_scope_idx": { + "name": "internal_mcp_catalog_scope_idx", + "columns": [ + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "internal_mcp_catalog_client_secret_id_secret_id_fk": { + "name": "internal_mcp_catalog_client_secret_id_secret_id_fk", + "tableFrom": "internal_mcp_catalog", + "tableTo": "secret", + "columnsFrom": [ + "client_secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "internal_mcp_catalog_local_config_secret_id_secret_id_fk": { + "name": "internal_mcp_catalog_local_config_secret_id_secret_id_fk", + "tableFrom": "internal_mcp_catalog", + "tableTo": "secret", + "columnsFrom": [ + "local_config_secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "internal_mcp_catalog_author_id_user_id_fk": { + "name": "internal_mcp_catalog_author_id_user_id_fk", + "tableFrom": "internal_mcp_catalog", + "tableTo": "user", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "internal_mcp_catalog_slug_unique": { + "name": "internal_mcp_catalog_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invitation": { + "name": "invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "invitation_organization_id_organization_id_fk": { + "name": "invitation_organization_id_organization_id_fk", + "tableFrom": "invitation", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "invitation_inviter_id_user_id_fk": { + "name": "invitation_inviter_id_user_id_fk", + "tableFrom": "invitation", + "tableTo": "user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.jwks": { + "name": "jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kb_chunks": { + "name": "kb_chunks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "document_id": { + "name": "document_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "chunk_index": { + "name": "chunk_index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "embedding": { + "name": "embedding", + "type": "vector(1536)", + "primaryKey": false, + "notNull": false + }, + "search_vector": { + "name": "search_vector", + "type": "tsvector", + "primaryKey": false, + "notNull": false + }, + "acl": { + "name": "acl", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "kb_chunks_document_id_idx": { + "name": "kb_chunks_document_id_idx", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kb_chunks_document_id_kb_documents_id_fk": { + "name": "kb_chunks_document_id_kb_documents_id_fk", + "tableFrom": "kb_chunks", + "tableTo": "kb_documents", + "columnsFrom": [ + "document_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kb_documents": { + "name": "kb_documents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "connector_id": { + "name": "connector_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_hash": { + "name": "content_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_url": { + "name": "source_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "acl": { + "name": "acl", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "embedding_status": { + "name": "embedding_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "chunk_count": { + "name": "chunk_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "kb_documents_org_id_idx": { + "name": "kb_documents_org_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "kb_documents_source_idx": { + "name": "kb_documents_source_idx", + "columns": [ + { + "expression": "connector_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "source_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kb_documents_connector_id_knowledge_base_connectors_id_fk": { + "name": "kb_documents_connector_id_knowledge_base_connectors_id_fk", + "tableFrom": "kb_documents", + "tableTo": "knowledge_base_connectors", + "columnsFrom": [ + "connector_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knowledge_base_connector_assignment": { + "name": "knowledge_base_connector_assignment", + "schema": "", + "columns": { + "knowledge_base_id": { + "name": "knowledge_base_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "connector_id": { + "name": "connector_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "kb_connector_assignment_kb_id_idx": { + "name": "kb_connector_assignment_kb_id_idx", + "columns": [ + { + "expression": "knowledge_base_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "kb_connector_assignment_connector_id_idx": { + "name": "kb_connector_assignment_connector_id_idx", + "columns": [ + { + "expression": "connector_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "knowledge_base_connector_assignment_knowledge_base_id_knowledge_bases_id_fk": { + "name": "knowledge_base_connector_assignment_knowledge_base_id_knowledge_bases_id_fk", + "tableFrom": "knowledge_base_connector_assignment", + "tableTo": "knowledge_bases", + "columnsFrom": [ + "knowledge_base_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knowledge_base_connector_assignment_connector_id_knowledge_base_connectors_id_fk": { + "name": "knowledge_base_connector_assignment_connector_id_knowledge_base_connectors_id_fk", + "tableFrom": "knowledge_base_connector_assignment", + "tableTo": "knowledge_base_connectors", + "columnsFrom": [ + "connector_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knowledge_base_connectors": { + "name": "knowledge_base_connectors", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connector_type": { + "name": "connector_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "secret_id": { + "name": "secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "schedule": { + "name": "schedule", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'0 */6 * * *'" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "last_sync_at": { + "name": "last_sync_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "last_sync_status": { + "name": "last_sync_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_sync_error": { + "name": "last_sync_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "checkpoint": { + "name": "checkpoint", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "knowledge_base_connectors_organization_id_idx": { + "name": "knowledge_base_connectors_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "knowledge_base_connectors_secret_id_secret_id_fk": { + "name": "knowledge_base_connectors_secret_id_secret_id_fk", + "tableFrom": "knowledge_base_connectors", + "tableTo": "secret", + "columnsFrom": [ + "secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knowledge_bases": { + "name": "knowledge_bases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'org-wide'" + }, + "team_ids": { + "name": "team_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "knowledge_bases_organization_id_idx": { + "name": "knowledge_bases_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_keys": { + "name": "label_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "label_keys_key_unique": { + "name": "label_keys_key_unique", + "nullsNotDistinct": false, + "columns": [ + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_values": { + "name": "label_values", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "label_values_value_unique": { + "name": "label_values_value_unique", + "nullsNotDistinct": false, + "columns": [ + "value" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.limit_model_usage": { + "name": "limit_model_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "limit_id": { + "name": "limit_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "current_usage_tokens_in": { + "name": "current_usage_tokens_in", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "current_usage_tokens_out": { + "name": "current_usage_tokens_out", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "limit_model_usage_limit_id_idx": { + "name": "limit_model_usage_limit_id_idx", + "columns": [ + { + "expression": "limit_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "limit_model_usage_limit_model_idx": { + "name": "limit_model_usage_limit_model_idx", + "columns": [ + { + "expression": "limit_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "model", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "limit_model_usage_limit_id_limits_id_fk": { + "name": "limit_model_usage_limit_id_limits_id_fk", + "tableFrom": "limit_model_usage", + "tableTo": "limits", + "columnsFrom": [ + "limit_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.limits": { + "name": "limits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "entity_type": { + "name": "entity_type", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "limit_type": { + "name": "limit_type", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "limit_value": { + "name": "limit_value", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "mcp_server_name": { + "name": "mcp_server_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "tool_name": { + "name": "tool_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "last_cleanup": { + "name": "last_cleanup", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "limits_entity_idx": { + "name": "limits_entity_idx", + "columns": [ + { + "expression": "entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "limits_type_idx": { + "name": "limits_type_idx", + "columns": [ + { + "expression": "limit_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_catalog_labels": { + "name": "mcp_catalog_labels", + "schema": "", + "columns": { + "catalog_id": { + "name": "catalog_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key_id": { + "name": "key_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value_id": { + "name": "value_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "mcp_catalog_labels_catalog_id_internal_mcp_catalog_id_fk": { + "name": "mcp_catalog_labels_catalog_id_internal_mcp_catalog_id_fk", + "tableFrom": "mcp_catalog_labels", + "tableTo": "internal_mcp_catalog", + "columnsFrom": [ + "catalog_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mcp_catalog_labels_key_id_label_keys_id_fk": { + "name": "mcp_catalog_labels_key_id_label_keys_id_fk", + "tableFrom": "mcp_catalog_labels", + "tableTo": "label_keys", + "columnsFrom": [ + "key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mcp_catalog_labels_value_id_label_values_id_fk": { + "name": "mcp_catalog_labels_value_id_label_values_id_fk", + "tableFrom": "mcp_catalog_labels", + "tableTo": "label_values", + "columnsFrom": [ + "value_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "mcp_catalog_labels_catalog_id_key_id_pk": { + "name": "mcp_catalog_labels_catalog_id_key_id_pk", + "columns": [ + "catalog_id", + "key_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_catalog_team": { + "name": "mcp_catalog_team", + "schema": "", + "columns": { + "catalog_id": { + "name": "catalog_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "mcp_catalog_team_catalog_id_internal_mcp_catalog_id_fk": { + "name": "mcp_catalog_team_catalog_id_internal_mcp_catalog_id_fk", + "tableFrom": "mcp_catalog_team", + "tableTo": "internal_mcp_catalog", + "columnsFrom": [ + "catalog_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mcp_catalog_team_team_id_team_id_fk": { + "name": "mcp_catalog_team_team_id_team_id_fk", + "tableFrom": "mcp_catalog_team", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "mcp_catalog_team_catalog_id_team_id_pk": { + "name": "mcp_catalog_team_catalog_id_team_id_pk", + "columns": [ + "catalog_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_http_sessions": { + "name": "mcp_http_sessions", + "schema": "", + "columns": { + "connection_key": { + "name": "connection_key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_endpoint_url": { + "name": "session_endpoint_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_endpoint_pod_name": { + "name": "session_endpoint_pod_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_server_installation_request": { + "name": "mcp_server_installation_request", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "external_catalog_id": { + "name": "external_catalog_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_by": { + "name": "requested_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "request_reason": { + "name": "request_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "custom_server_config": { + "name": "custom_server_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'null'::jsonb" + }, + "admin_response": { + "name": "admin_response", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reviewed_by": { + "name": "reviewed_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reviewed_at": { + "name": "reviewed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "mcp_server_installation_request_requested_by_user_id_fk": { + "name": "mcp_server_installation_request_requested_by_user_id_fk", + "tableFrom": "mcp_server_installation_request", + "tableTo": "user", + "columnsFrom": [ + "requested_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mcp_server_installation_request_reviewed_by_user_id_fk": { + "name": "mcp_server_installation_request_reviewed_by_user_id_fk", + "tableFrom": "mcp_server_installation_request", + "tableTo": "user", + "columnsFrom": [ + "reviewed_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_server_user": { + "name": "mcp_server_user", + "schema": "", + "columns": { + "mcp_server_id": { + "name": "mcp_server_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "mcp_server_user_mcp_server_id_mcp_server_id_fk": { + "name": "mcp_server_user_mcp_server_id_mcp_server_id_fk", + "tableFrom": "mcp_server_user", + "tableTo": "mcp_server", + "columnsFrom": [ + "mcp_server_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mcp_server_user_user_id_user_id_fk": { + "name": "mcp_server_user_user_id_user_id_fk", + "tableFrom": "mcp_server_user", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "mcp_server_user_mcp_server_id_user_id_pk": { + "name": "mcp_server_user_mcp_server_id_user_id_pk", + "columns": [ + "mcp_server_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_server": { + "name": "mcp_server", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "catalog_id": { + "name": "catalog_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "server_type": { + "name": "server_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "secret_id": { + "name": "secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owner_id": { + "name": "owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reinstall_required": { + "name": "reinstall_required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "local_installation_status": { + "name": "local_installation_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "local_installation_error": { + "name": "local_installation_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "oauth_refresh_error": { + "name": "oauth_refresh_error", + "type": "oauth_refresh_error_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "oauth_refresh_failed_at": { + "name": "oauth_refresh_failed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "mcp_server_catalog_id_internal_mcp_catalog_id_fk": { + "name": "mcp_server_catalog_id_internal_mcp_catalog_id_fk", + "tableFrom": "mcp_server", + "tableTo": "internal_mcp_catalog", + "columnsFrom": [ + "catalog_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "mcp_server_secret_id_secret_id_fk": { + "name": "mcp_server_secret_id_secret_id_fk", + "tableFrom": "mcp_server", + "tableTo": "secret", + "columnsFrom": [ + "secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "mcp_server_owner_id_user_id_fk": { + "name": "mcp_server_owner_id_user_id_fk", + "tableFrom": "mcp_server", + "tableTo": "user", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "mcp_server_team_id_team_id_fk": { + "name": "mcp_server_team_id_team_id_fk", + "tableFrom": "mcp_server", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mcp_tool_calls": { + "name": "mcp_tool_calls", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "mcp_server_name": { + "name": "mcp_server_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "method": { + "name": "method", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tool_call": { + "name": "tool_call", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "tool_result": { + "name": "tool_result", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_method": { + "name": "auth_method", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "mcp_tool_calls_agent_id_idx": { + "name": "mcp_tool_calls_agent_id_idx", + "columns": [ + { + "expression": "agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "mcp_tool_calls_created_at_idx": { + "name": "mcp_tool_calls_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "mcp_tool_calls_agent_id_agents_id_fk": { + "name": "mcp_tool_calls_agent_id_agents_id_fk", + "tableFrom": "mcp_tool_calls", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "mcp_tool_calls_user_id_user_id_fk": { + "name": "mcp_tool_calls_user_id_user_id_fk", + "tableFrom": "mcp_tool_calls", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.member": { + "name": "member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "default_agent_id": { + "name": "default_agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "member_organization_id_organization_id_fk": { + "name": "member_organization_id_organization_id_fk", + "tableFrom": "member", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_user_id_user_id_fk": { + "name": "member_user_id_user_id_fk", + "tableFrom": "member", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_default_agent_id_agents_id_fk": { + "name": "member_default_agent_id_agents_id_fk", + "tableFrom": "member", + "tableTo": "agents", + "columnsFrom": [ + "default_agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.messages": { + "name": "messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "conversation_id": { + "name": "conversation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "messages_conversation_id_idx": { + "name": "messages_conversation_id_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "messages_conversation_id_conversations_id_fk": { + "name": "messages_conversation_id_conversations_id_fk", + "tableFrom": "messages", + "tableTo": "conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.models": { + "name": "models", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model_id": { + "name": "model_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "context_length": { + "name": "context_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "input_modalities": { + "name": "input_modalities", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "output_modalities": { + "name": "output_modalities", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "supports_tool_calling": { + "name": "supports_tool_calling", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "prompt_price_per_token": { + "name": "prompt_price_per_token", + "type": "numeric(20, 12)", + "primaryKey": false, + "notNull": false + }, + "completion_price_per_token": { + "name": "completion_price_per_token", + "type": "numeric(20, 12)", + "primaryKey": false, + "notNull": false + }, + "custom_price_per_million_input": { + "name": "custom_price_per_million_input", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "custom_price_per_million_output": { + "name": "custom_price_per_million_output", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "discovered_via_llm_proxy": { + "name": "discovered_via_llm_proxy", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "models_provider_model_idx": { + "name": "models_provider_model_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "model_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "models_external_id_idx": { + "name": "models_external_id_idx", + "columns": [ + { + "expression": "external_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "models_provider_model_unique": { + "name": "models_provider_model_unique", + "nullsNotDistinct": false, + "columns": [ + "provider", + "model_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_access_token": { + "name": "oauth_access_token", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_id": { + "name": "refresh_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_access_token_client_id_oauth_client_client_id_fk": { + "name": "oauth_access_token_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "oauth_client", + "columnsFrom": [ + "client_id" + ], + "columnsTo": [ + "client_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_access_token_session_id_session_id_fk": { + "name": "oauth_access_token_session_id_session_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "oauth_access_token_user_id_user_id_fk": { + "name": "oauth_access_token_user_id_user_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_access_token_refresh_id_oauth_refresh_token_id_fk": { + "name": "oauth_access_token_refresh_id_oauth_refresh_token_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "oauth_refresh_token", + "columnsFrom": [ + "refresh_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_access_token_token_unique": { + "name": "oauth_access_token_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_client": { + "name": "oauth_client", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_secret": { + "name": "client_secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uri": { + "name": "uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contacts": { + "name": "contacts", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "tos": { + "name": "tos", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "policy": { + "name": "policy", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_id": { + "name": "software_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_version": { + "name": "software_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_statement": { + "name": "software_statement", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "skip_consent": { + "name": "skip_consent", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "enable_end_session": { + "name": "enable_end_session", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redirect_uris": { + "name": "redirect_uris", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "post_logout_redirect_uris": { + "name": "post_logout_redirect_uris", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "token_endpoint_auth_method": { + "name": "token_endpoint_auth_method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "grant_types": { + "name": "grant_types", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "response_types": { + "name": "response_types", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "public": { + "name": "public", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_client_user_id_user_id_fk": { + "name": "oauth_client_user_id_user_id_fk", + "tableFrom": "oauth_client", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_client_client_id_unique": { + "name": "oauth_client_client_id_unique", + "nullsNotDistinct": false, + "columns": [ + "client_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_consent": { + "name": "oauth_consent", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_consent_client_id_oauth_client_client_id_fk": { + "name": "oauth_consent_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_consent", + "tableTo": "oauth_client", + "columnsFrom": [ + "client_id" + ], + "columnsTo": [ + "client_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_consent_user_id_user_id_fk": { + "name": "oauth_consent_user_id_user_id_fk", + "tableFrom": "oauth_consent", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_refresh_token": { + "name": "oauth_refresh_token", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "revoked": { + "name": "revoked", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_refresh_token_client_id_oauth_client_client_id_fk": { + "name": "oauth_refresh_token_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_refresh_token", + "tableTo": "oauth_client", + "columnsFrom": [ + "client_id" + ], + "columnsTo": [ + "client_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_refresh_token_session_id_session_id_fk": { + "name": "oauth_refresh_token_session_id_session_id_fk", + "tableFrom": "oauth_refresh_token", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "oauth_refresh_token_user_id_user_id_fk": { + "name": "oauth_refresh_token_user_id_user_id_fk", + "tableFrom": "oauth_refresh_token", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.optimization_rules": { + "name": "optimization_rules", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "entity_type": { + "name": "entity_type", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "conditions": { + "name": "conditions", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_model": { + "name": "target_model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "optimization_rules_entity_idx": { + "name": "optimization_rules_entity_idx", + "columns": [ + { + "expression": "entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_role": { + "name": "organization_role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "organization_role_organization_id_organization_id_fk": { + "name": "organization_role_organization_id_organization_id_fk", + "tableFrom": "organization_role", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organization_role_organization_id_role_unique": { + "name": "organization_role_organization_id_role_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "role" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization": { + "name": "organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logo_dark": { + "name": "logo_dark", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "limit_cleanup_interval": { + "name": "limit_cleanup_interval", + "type": "varchar", + "primaryKey": false, + "notNull": false, + "default": "'1h'" + }, + "onboarding_complete": { + "name": "onboarding_complete", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'cosmic-night'" + }, + "custom_font": { + "name": "custom_font", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'lato'" + }, + "convert_tool_results_to_toon": { + "name": "convert_tool_results_to_toon", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "compression_scope": { + "name": "compression_scope", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'organization'" + }, + "global_tool_policy": { + "name": "global_tool_policy", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'permissive'" + }, + "allow_chat_file_uploads": { + "name": "allow_chat_file_uploads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "embedding_model": { + "name": "embedding_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "embedding_chat_api_key_id": { + "name": "embedding_chat_api_key_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "reranker_chat_api_key_id": { + "name": "reranker_chat_api_key_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "reranker_model": { + "name": "reranker_model", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organization_slug_unique": { + "name": "organization_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.processed_email": { + "name": "processed_email", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "message_id": { + "name": "message_id", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "processed_email_processed_at_idx": { + "name": "processed_email_processed_at_idx", + "columns": [ + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "processed_email_message_id_unique": { + "name": "processed_email_message_id_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.secret": { + "name": "secret", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true, + "default": "'secret'" + }, + "secret": { + "name": "secret", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_vault": { + "name": "is_vault", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_byos_vault": { + "name": "is_byos_vault", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tasks": { + "name": "tasks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "task_type": { + "name": "task_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt": { + "name": "attempt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "scheduled_for": { + "name": "scheduled_for", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "periodic": { + "name": "periodic", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tasks_dequeue_idx": { + "name": "tasks_dequeue_idx", + "columns": [ + { + "expression": "task_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scheduled_for", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "tasks_unique_periodic_idx": { + "name": "tasks_unique_periodic_idx", + "columns": [ + { + "expression": "task_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"tasks\".\"periodic\" = true AND \"tasks\".\"status\" IN ('pending', 'processing')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_external_group": { + "name": "team_external_group", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_identifier": { + "name": "group_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "team_external_group_team_id_team_id_fk": { + "name": "team_external_group_team_id_team_id_fk", + "tableFrom": "team_external_group", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "team_external_group_team_group_unique": { + "name": "team_external_group_team_group_unique", + "nullsNotDistinct": false, + "columns": [ + "team_id", + "group_identifier" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_member": { + "name": "team_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "synced_from_sso": { + "name": "synced_from_sso", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "team_member_team_id_team_id_fk": { + "name": "team_member_team_id_team_id_fk", + "tableFrom": "team_member", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_member_user_id_user_id_fk": { + "name": "team_member_user_id_user_id_fk", + "tableFrom": "team_member", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_token": { + "name": "team_token", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_organization_token": { + "name": "is_organization_token", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "secret_id": { + "name": "secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_start": { + "name": "token_start", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_team_token_org_id": { + "name": "idx_team_token_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_team_token_team_id": { + "name": "idx_team_token_team_id", + "columns": [ + { + "expression": "team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "team_token_organization_id_organization_id_fk": { + "name": "team_token_organization_id_organization_id_fk", + "tableFrom": "team_token", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_token_team_id_team_id_fk": { + "name": "team_token_team_id_team_id_fk", + "tableFrom": "team_token", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_token_secret_id_secret_id_fk": { + "name": "team_token_secret_id_secret_id_fk", + "tableFrom": "team_token", + "tableTo": "secret", + "columnsFrom": [ + "secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "team_token_organization_id_team_id_unique": { + "name": "team_token_organization_id_team_id_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "team_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_vault_folder": { + "name": "team_vault_folder", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "vault_path": { + "name": "vault_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "team_vault_folder_team_id_team_id_fk": { + "name": "team_vault_folder_team_id_team_id_fk", + "tableFrom": "team_vault_folder", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "team_vault_folder_team_id_unique": { + "name": "team_vault_folder_team_id_unique", + "nullsNotDistinct": false, + "columns": [ + "team_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team": { + "name": "team", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "convert_tool_results_to_toon": { + "name": "convert_tool_results_to_toon", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "team_organization_id_organization_id_fk": { + "name": "team_organization_id_organization_id_fk", + "tableFrom": "team", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_created_by_user_id_fk": { + "name": "team_created_by_user_id_fk", + "tableFrom": "team", + "tableTo": "user", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tool_invocation_policies": { + "name": "tool_invocation_policies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "tool_id": { + "name": "tool_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "conditions": { + "name": "conditions", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "tool_invocation_policies_tool_id_tools_id_fk": { + "name": "tool_invocation_policies_tool_id_tools_id_fk", + "tableFrom": "tool_invocation_policies", + "tableTo": "tools", + "columnsFrom": [ + "tool_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tools": { + "name": "tools", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "agent_id": { + "name": "agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "catalog_id": { + "name": "catalog_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "mcp_server_id": { + "name": "mcp_server_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "delegate_to_agent_id": { + "name": "delegate_to_agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "parameters": { + "name": "parameters", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "policies_auto_configured_at": { + "name": "policies_auto_configured_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "policies_auto_configuring_started_at": { + "name": "policies_auto_configuring_started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "policies_auto_configured_reasoning": { + "name": "policies_auto_configured_reasoning", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "policies_auto_configured_model": { + "name": "policies_auto_configured_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tools_delegate_to_agent_id_idx": { + "name": "tools_delegate_to_agent_id_idx", + "columns": [ + { + "expression": "delegate_to_agent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "tools_agent_id_agents_id_fk": { + "name": "tools_agent_id_agents_id_fk", + "tableFrom": "tools", + "tableTo": "agents", + "columnsFrom": [ + "agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tools_catalog_id_internal_mcp_catalog_id_fk": { + "name": "tools_catalog_id_internal_mcp_catalog_id_fk", + "tableFrom": "tools", + "tableTo": "internal_mcp_catalog", + "columnsFrom": [ + "catalog_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tools_mcp_server_id_mcp_server_id_fk": { + "name": "tools_mcp_server_id_mcp_server_id_fk", + "tableFrom": "tools", + "tableTo": "mcp_server", + "columnsFrom": [ + "mcp_server_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "tools_delegate_to_agent_id_agents_id_fk": { + "name": "tools_delegate_to_agent_id_agents_id_fk", + "tableFrom": "tools", + "tableTo": "agents", + "columnsFrom": [ + "delegate_to_agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "tools_catalog_id_name_agent_id_delegate_to_agent_id_unique": { + "name": "tools_catalog_id_name_agent_id_delegate_to_agent_id_unique", + "nullsNotDistinct": false, + "columns": [ + "catalog_id", + "name", + "agent_id", + "delegate_to_agent_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.trusted_data_policies": { + "name": "trusted_data_policies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "tool_id": { + "name": "tool_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "conditions": { + "name": "conditions", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'mark_as_trusted'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "trusted_data_policies_tool_id_tools_id_fk": { + "name": "trusted_data_policies_tool_id_tools_id_fk", + "tableFrom": "trusted_data_policies", + "tableTo": "tools", + "columnsFrom": [ + "tool_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.two_factor": { + "name": "two_factor", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "backup_codes": { + "name": "backup_codes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "two_factor_user_id_user_id_fk": { + "name": "two_factor_user_id_user_id_fk", + "tableFrom": "two_factor", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_token": { + "name": "user_token", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "secret_id": { + "name": "secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_start": { + "name": "token_start", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_user_token_org_id": { + "name": "idx_user_token_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_user_token_user_id": { + "name": "idx_user_token_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_token_organization_id_organization_id_fk": { + "name": "user_token_organization_id_organization_id_fk", + "tableFrom": "user_token", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_token_user_id_user_id_fk": { + "name": "user_token_user_id_user_id_fk", + "tableFrom": "user_token", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_token_secret_id_secret_id_fk": { + "name": "user_token_secret_id_secret_id_fk", + "tableFrom": "user_token", + "tableTo": "secret", + "columnsFrom": [ + "secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_token_organization_id_user_id_unique": { + "name": "user_token_organization_id_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "two_factor_enabled": { + "name": "two_factor_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.virtual_api_keys": { + "name": "virtual_api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "chat_api_key_id": { + "name": "chat_api_key_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "secret_id": { + "name": "secret_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_start": { + "name": "token_start", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_virtual_api_key_chat_api_key_id": { + "name": "idx_virtual_api_key_chat_api_key_id", + "columns": [ + { + "expression": "chat_api_key_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_virtual_api_key_token_start": { + "name": "idx_virtual_api_key_token_start", + "columns": [ + { + "expression": "token_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "virtual_api_keys_chat_api_key_id_chat_api_keys_id_fk": { + "name": "virtual_api_keys_chat_api_key_id_chat_api_keys_id_fk", + "tableFrom": "virtual_api_keys", + "tableTo": "chat_api_keys", + "columnsFrom": [ + "chat_api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "virtual_api_keys_secret_id_secret_id_fk": { + "name": "virtual_api_keys_secret_id_secret_id_fk", + "tableFrom": "virtual_api_keys", + "tableTo": "secret", + "columnsFrom": [ + "secret_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.agent_scope": { + "name": "agent_scope", + "schema": "public", + "values": [ + "personal", + "team", + "org" + ] + }, + "public.conversation_share_visibility": { + "name": "conversation_share_visibility", + "schema": "public", + "values": [ + "organization" + ] + }, + "public.mcp_catalog_scope": { + "name": "mcp_catalog_scope", + "schema": "public", + "values": [ + "personal", + "team", + "org" + ] + }, + "public.oauth_refresh_error_enum": { + "name": "oauth_refresh_error_enum", + "schema": "public", + "values": [ + "refresh_failed", + "no_refresh_token" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/platform/backend/src/database/migrations/meta/_journal.json b/platform/backend/src/database/migrations/meta/_journal.json index b51864cca1..4b8c7056ad 100644 --- a/platform/backend/src/database/migrations/meta/_journal.json +++ b/platform/backend/src/database/migrations/meta/_journal.json @@ -1219,6 +1219,13 @@ "when": 1773064802202, "tag": "0173_heavy_marvel_boy", "breakpoints": true + }, + { + "idx": 174, + "version": "7", + "when": 1773081912528, + "tag": "0174_curved_absorbing_man", + "breakpoints": true } ] } \ No newline at end of file diff --git a/platform/backend/src/database/schemas/internal-mcp-catalog.ts b/platform/backend/src/database/schemas/internal-mcp-catalog.ts index 64da44ec91..deda80f687 100644 --- a/platform/backend/src/database/schemas/internal-mcp-catalog.ts +++ b/platform/backend/src/database/schemas/internal-mcp-catalog.ts @@ -22,7 +22,8 @@ const internalMcpCatalogTable = pgTable( "internal_mcp_catalog", { id: uuid("id").primaryKey().defaultRandom(), - name: text("name").notNull(), + slug: text("slug").notNull().unique(), + displayName: text("display_name").notNull(), version: text("version"), description: text("description"), instructions: text("instructions"), diff --git a/platform/backend/src/database/seed.ts b/platform/backend/src/database/seed.ts index d21aa6c07d..293246d536 100644 --- a/platform/backend/src/database/seed.ts +++ b/platform/backend/src/database/seed.ts @@ -200,7 +200,7 @@ async function seedArchestraCatalogAndTools(): Promise { * Each user gets their own personal Playwright server instance when they click the Browser button. */ async function seedPlaywrightCatalog(): Promise { - const LEGACY_PLAYWRIGHT_MCP_SERVER_NAME = "playwright-browser"; + const LEGACY_PLAYWRIGHT_MCP_SERVER_SLUG = "playwright-browser"; const playwrightLocalConfig = { // Pinned to v0.0.64 digest because v0.0.67 renamed --no-sandbox to --no-chromium-sandbox // but the image entrypoint still uses --no-sandbox, causing immediate crashes. @@ -245,29 +245,29 @@ async function seedPlaywrightCatalog(): Promise { let existingCatalog = await InternalMcpCatalogModel.findById( PLAYWRIGHT_MCP_CATALOG_ID, ); - const legacyCatalogByName = await InternalMcpCatalogModel.findByName( - LEGACY_PLAYWRIGHT_MCP_SERVER_NAME, + const legacyCatalogBySlug = await InternalMcpCatalogModel.findBySlug( + LEGACY_PLAYWRIGHT_MCP_SERVER_SLUG, ); // One-time migration: remove legacy playwright catalog installations/resources. - // This runs only when the old catalog name is present in the environment. + // This runs only when the old catalog slug is present in the environment. if ( - existingCatalog?.name === LEGACY_PLAYWRIGHT_MCP_SERVER_NAME || - legacyCatalogByName + existingCatalog?.slug === LEGACY_PLAYWRIGHT_MCP_SERVER_SLUG || + legacyCatalogBySlug ) { const catalogIdsToDelete = new Set(); - if (existingCatalog?.name === LEGACY_PLAYWRIGHT_MCP_SERVER_NAME) { + if (existingCatalog?.slug === LEGACY_PLAYWRIGHT_MCP_SERVER_SLUG) { catalogIdsToDelete.add(existingCatalog.id); } - if (legacyCatalogByName) { - catalogIdsToDelete.add(legacyCatalogByName.id); + if (legacyCatalogBySlug) { + catalogIdsToDelete.add(legacyCatalogBySlug.id); } for (const catalogId of catalogIdsToDelete) { const deleted = await InternalMcpCatalogModel.delete(catalogId); if (deleted) { logger.info( - { catalogId, legacyCatalogName: LEGACY_PLAYWRIGHT_MCP_SERVER_NAME }, + { catalogId, legacyCatalogName: LEGACY_PLAYWRIGHT_MCP_SERVER_SLUG }, "Removed legacy Playwright catalog and related installations/resources", ); } @@ -282,7 +282,8 @@ async function seedPlaywrightCatalog(): Promise { .insert(schema.internalMcpCatalogTable) .values({ id: PLAYWRIGHT_MCP_CATALOG_ID, - name: PLAYWRIGHT_MCP_SERVER_NAME, + slug: PLAYWRIGHT_MCP_SERVER_NAME, + displayName: PLAYWRIGHT_MCP_SERVER_NAME, description: "Browser automation for chat - each user gets their own isolated browser session", serverType: "local", @@ -304,7 +305,7 @@ async function seedTestMcpServer(): Promise { return; } - const existing = await InternalMcpCatalogModel.findByName( + const existing = await InternalMcpCatalogModel.findBySlug( "internal-dev-test-server", ); if (existing) { @@ -313,7 +314,8 @@ async function seedTestMcpServer(): Promise { } await InternalMcpCatalogModel.create({ - name: "internal-dev-test-server", + slug: "internal-dev-test-server", + displayName: "internal-dev-test-server", description: "Simple test MCP server for development. Has one tool that prints an env var.", serverType: "local", diff --git a/platform/backend/src/models/agent-tool.test.ts b/platform/backend/src/models/agent-tool.test.ts index 8dc494c227..0d45c8ef0b 100644 --- a/platform/backend/src/models/agent-tool.test.ts +++ b/platform/backend/src/models/agent-tool.test.ts @@ -470,8 +470,14 @@ describe("AgentToolModel.findAll", () => { makeInternalMcpCatalog, }) => { const agent = await makeAgent(); - const catalog1 = await makeInternalMcpCatalog({ name: "Catalog 1" }); - const catalog2 = await makeInternalMcpCatalog({ name: "Catalog 2" }); + const catalog1 = await makeInternalMcpCatalog({ + slug: "catalog-1", + displayName: "Catalog 1", + }); + const catalog2 = await makeInternalMcpCatalog({ + slug: "catalog-2", + displayName: "Catalog 2", + }); const tool1 = await makeTool({ name: "tool-1", catalogId: catalog1.id }); const tool2 = await makeTool({ name: "tool-2", catalogId: catalog2.id }); diff --git a/platform/backend/src/models/agent.test.ts b/platform/backend/src/models/agent.test.ts index 95dd25c014..178b82a505 100644 --- a/platform/backend/src/models/agent.test.ts +++ b/platform/backend/src/models/agent.test.ts @@ -1618,7 +1618,8 @@ describe("AgentModel", () => { const catalog = await makeInternalMcpCatalog({ id: PLAYWRIGHT_MCP_CATALOG_ID, - name: "Playwright", + slug: "Playwright", + displayName: "Playwright", serverType: "builtin", }); diff --git a/platform/backend/src/models/internal-mcp-catalog.test.ts b/platform/backend/src/models/internal-mcp-catalog.test.ts index 5b146a2e9a..b7d9cb2538 100644 --- a/platform/backend/src/models/internal-mcp-catalog.test.ts +++ b/platform/backend/src/models/internal-mcp-catalog.test.ts @@ -24,7 +24,8 @@ describe("InternalMcpCatalogModel", () => { // Create catalog item with secret references using the model directly const catalog = await InternalMcpCatalogModel.create({ - name: "test-catalog-with-secrets", + slug: "test-catalog-with-secrets", + displayName: "test-catalog-with-secrets", serverType: "remote", clientSecretId: oauthSecret.id, localConfigSecretId: envSecret.id, @@ -92,7 +93,8 @@ describe("InternalMcpCatalogModel", () => { // Create catalog item with secret references const catalog = await InternalMcpCatalogModel.create({ - name: "test-catalog-no-expand", + slug: "test-catalog-no-expand", + displayName: "test-catalog-no-expand", serverType: "remote", clientSecretId: oauthSecret.id, localConfigSecretId: envSecret.id, @@ -138,11 +140,13 @@ describe("InternalMcpCatalogModel", () => { makeInternalMcpCatalog, }) => { const catalog1 = await makeInternalMcpCatalog({ - name: "test-catalog-1", + slug: "test-catalog-1", + displayName: "test-catalog-1", serverType: "remote", }); const catalog2 = await makeInternalMcpCatalog({ - name: "test-catalog-2", + slug: "test-catalog-2", + displayName: "test-catalog-2", serverType: "local", }); const nonExistentId = "00000000-0000-0000-0000-000000000000"; @@ -162,13 +166,13 @@ describe("InternalMcpCatalogModel", () => { const item1 = catalogItemsMap.get(catalog1.id); expect(item1).toBeDefined(); expect(item1?.id).toBe(catalog1.id); - expect(item1?.name).toBe("test-catalog-1"); + expect(item1?.slug).toBe("test-catalog-1"); expect(item1?.serverType).toBe("remote"); const item2 = catalogItemsMap.get(catalog2.id); expect(item2).toBeDefined(); expect(item2?.id).toBe(catalog2.id); - expect(item2?.name).toBe("test-catalog-2"); + expect(item2?.slug).toBe("test-catalog-2"); expect(item2?.serverType).toBe("local"); }); @@ -196,7 +200,8 @@ describe("InternalMcpCatalogModel", () => { makeInternalMcpCatalog, }) => { const catalog = await makeInternalMcpCatalog({ - name: "test-catalog", + slug: "test-catalog", + displayName: "test-catalog", serverType: "remote", }); @@ -215,7 +220,8 @@ describe("InternalMcpCatalogModel", () => { describe("labels integration", () => { test("create with labels returns labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-with-labels", + slug: "catalog-with-labels", + displayName: "catalog-with-labels", serverType: "remote", labels: [ { key: "category", value: "database" }, @@ -232,7 +238,8 @@ describe("InternalMcpCatalogModel", () => { test("create without labels returns empty labels array", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-no-labels", + slug: "catalog-no-labels", + displayName: "catalog-no-labels", serverType: "remote", }); @@ -241,7 +248,8 @@ describe("InternalMcpCatalogModel", () => { test("findById returns labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-find-by-id-labels", + slug: "catalog-find-by-id-labels", + displayName: "catalog-find-by-id-labels", serverType: "remote", labels: [{ key: "env", value: "prod" }], }); @@ -258,7 +266,8 @@ describe("InternalMcpCatalogModel", () => { test("findByIdWithResolvedSecrets returns labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-resolved-secrets-labels", + slug: "catalog-resolved-secrets-labels", + displayName: "catalog-resolved-secrets-labels", serverType: "remote", labels: [{ key: "scope", value: "internal" }], }); @@ -273,15 +282,16 @@ describe("InternalMcpCatalogModel", () => { expect(found?.labels[0].value).toBe("internal"); }); - test("findByName returns labels", async () => { - const uniqueName = `catalog-find-by-name-${Date.now()}`; + test("findBySlug returns labels", async () => { + const uniqueSlug = `catalog-find-by-slug-${Date.now()}`; await InternalMcpCatalogModel.create({ - name: uniqueName, + slug: uniqueSlug, + displayName: uniqueSlug, serverType: "remote", labels: [{ key: "type", value: "ai" }], }); - const found = await InternalMcpCatalogModel.findByName(uniqueName); + const found = await InternalMcpCatalogModel.findBySlug(uniqueSlug); expect(found).not.toBeNull(); expect(found?.labels).toHaveLength(1); @@ -291,7 +301,8 @@ describe("InternalMcpCatalogModel", () => { test("findAll returns labels for all items", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-find-all-labels", + slug: "catalog-find-all-labels", + displayName: "catalog-find-all-labels", serverType: "remote", labels: [ { key: "region", value: "us-east" }, @@ -312,7 +323,8 @@ describe("InternalMcpCatalogModel", () => { test("searchByQuery returns labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "unique-searchable-catalog-xyz", + slug: "unique-searchable-catalog-xyz", + displayName: "unique-searchable-catalog-xyz", serverType: "remote", labels: [{ key: "search-label", value: "found" }], }); @@ -330,7 +342,8 @@ describe("InternalMcpCatalogModel", () => { test("getByIds returns labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-get-by-ids-labels", + slug: "catalog-get-by-ids-labels", + displayName: "catalog-get-by-ids-labels", serverType: "remote", labels: [{ key: "bulk", value: "yes" }], }); @@ -346,7 +359,8 @@ describe("InternalMcpCatalogModel", () => { test("update with labels replaces existing labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-update-labels", + slug: "catalog-update-labels", + displayName: "catalog-update-labels", serverType: "remote", labels: [{ key: "version", value: "v1" }], }); @@ -368,17 +382,19 @@ describe("InternalMcpCatalogModel", () => { test("update without labels does not touch existing labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-update-no-labels", + slug: "catalog-update-no-labels", + displayName: "catalog-update-no-labels", serverType: "remote", labels: [{ key: "keep", value: "me" }], }); const updated = await InternalMcpCatalogModel.update(catalog.id, { - name: "catalog-update-no-labels-renamed", + slug: "catalog-update-no-labels-renamed", + displayName: "catalog-update-no-labels-renamed", }); expect(updated).not.toBeNull(); - expect(updated?.name).toBe("catalog-update-no-labels-renamed"); + expect(updated?.slug).toBe("catalog-update-no-labels-renamed"); expect(updated?.labels).toHaveLength(1); expect(updated?.labels[0].key).toBe("keep"); expect(updated?.labels[0].value).toBe("me"); @@ -386,7 +402,8 @@ describe("InternalMcpCatalogModel", () => { test("delete cascades labels", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "catalog-delete-cascade", + slug: "catalog-delete-cascade", + displayName: "catalog-delete-cascade", serverType: "remote", labels: [{ key: "delete-me", value: "cascade" }], }); @@ -417,7 +434,8 @@ describe("InternalMcpCatalogModel", () => { const catalog = await InternalMcpCatalogModel.create( { - name: "scoped-catalog", + slug: "scoped-catalog", + displayName: "scoped-catalog", serverType: "remote", scope: "personal", }, @@ -441,7 +459,8 @@ describe("InternalMcpCatalogModel", () => { const catalog = await InternalMcpCatalogModel.create( { - name: "team-scoped-catalog", + slug: "team-scoped-catalog", + displayName: "team-scoped-catalog", serverType: "remote", scope: "team", teams: [team.id], @@ -526,7 +545,8 @@ describe("InternalMcpCatalogModel", () => { const org = await makeOrganization(); await makeInternalMcpCatalog({ - name: "searchscope-personal-item", + slug: "searchscope-personal-item", + displayName: "searchscope-personal-item", scope: "personal", organizationId: org.id, authorId: author.id, @@ -538,7 +558,7 @@ describe("InternalMcpCatalogModel", () => { { expandSecrets: false, userId: author.id, isAdmin: false }, ); expect( - authorResults.some((r) => r.name === "searchscope-personal-item"), + authorResults.some((r) => r.slug === "searchscope-personal-item"), ).toBe(true); // Other user does not @@ -547,7 +567,7 @@ describe("InternalMcpCatalogModel", () => { { expandSecrets: false, userId: otherUser.id, isAdmin: false }, ); expect( - otherResults.some((r) => r.name === "searchscope-personal-item"), + otherResults.some((r) => r.slug === "searchscope-personal-item"), ).toBe(false); }); }); @@ -590,7 +610,7 @@ describe("InternalMcpCatalogModel", () => { ); expect(archestraCatalog).toBeDefined(); - expect(archestraCatalog?.name).toBe("Archestra"); + expect(archestraCatalog?.slug).toBe("archestra"); expect(archestraCatalog?.serverType).toBe("builtin"); }); }); diff --git a/platform/backend/src/models/internal-mcp-catalog.ts b/platform/backend/src/models/internal-mcp-catalog.ts index 8608323dfd..1519b4bf49 100644 --- a/platform/backend/src/models/internal-mcp-catalog.ts +++ b/platform/backend/src/models/internal-mcp-catalog.ts @@ -18,6 +18,11 @@ class InternalMcpCatalogModel { ): Promise { const { labels, teams, ...dbValues } = catalogItem; + // Ensure slug is unique by appending a short suffix if a duplicate exists + dbValues.slug = await InternalMcpCatalogModel.ensureUniqueSlug( + dbValues.slug, + ); + const insertValues = { ...dbValues, ...(context?.organizationId @@ -108,7 +113,8 @@ class InternalMcpCatalogModel { let dbItems: Array; const searchCondition = or( - ilike(schema.internalMcpCatalogTable.name, `%${query}%`), + ilike(schema.internalMcpCatalogTable.slug, `%${query}%`), + ilike(schema.internalMcpCatalogTable.displayName, `%${query}%`), ilike(schema.internalMcpCatalogTable.description, `%${query}%`), ); @@ -239,11 +245,11 @@ class InternalMcpCatalogModel { return result; } - static async findByName(name: string): Promise { + static async findBySlug(slug: string): Promise { const [dbItem] = await db .select() .from(schema.internalMcpCatalogTable) - .where(eq(schema.internalMcpCatalogTable.name, name)); + .where(eq(schema.internalMcpCatalogTable.slug, slug)); if (!dbItem) { return null; @@ -487,6 +493,25 @@ class InternalMcpCatalogModel { })); } + /** + * Ensure slug is unique. If a catalog item with the same slug already exists, + * append a short random suffix (first 8 chars of a UUID). + */ + private static async ensureUniqueSlug(slug: string): Promise { + const existing = await db + .select({ id: schema.internalMcpCatalogTable.id }) + .from(schema.internalMcpCatalogTable) + .where(eq(schema.internalMcpCatalogTable.slug, slug)) + .limit(1); + + if (existing.length === 0) { + return slug; + } + + const suffix = crypto.randomUUID().substring(0, 4); + return `${slug}-${suffix}`; + } + /** * Populate authorName for catalog items that have an authorId. */ diff --git a/platform/backend/src/models/mcp-catalog-team.test.ts b/platform/backend/src/models/mcp-catalog-team.test.ts index 9b4207506b..fb5fcd2e0b 100644 --- a/platform/backend/src/models/mcp-catalog-team.test.ts +++ b/platform/backend/src/models/mcp-catalog-team.test.ts @@ -235,19 +235,22 @@ test("findAll with scope filtering returns correct items", async ({ const orgCatalog = await makeInternalMcpCatalog({ scope: "org", organizationId: org.id, - name: "scope-test-org", + slug: "scope-test-org", + displayName: "scope-test-org", }); const personalCatalog = await makeInternalMcpCatalog({ scope: "personal", organizationId: org.id, authorId: author.id, - name: "scope-test-personal", + slug: "scope-test-personal", + displayName: "scope-test-personal", }); const teamCatalog = await makeInternalMcpCatalog({ scope: "team", organizationId: org.id, teams: [team.id], - name: "scope-test-team", + slug: "scope-test-team", + displayName: "scope-test-team", }); // Author can see all 3 @@ -256,10 +259,10 @@ test("findAll with scope filtering returns correct items", async ({ userId: author.id, isAdmin: false, }); - const authorNames = authorItems.map((i) => i.name); - expect(authorNames).toContain(orgCatalog.name); - expect(authorNames).toContain(personalCatalog.name); - expect(authorNames).toContain(teamCatalog.name); + const authorSlugs = authorItems.map((i) => i.slug); + expect(authorSlugs).toContain(orgCatalog.slug); + expect(authorSlugs).toContain(personalCatalog.slug); + expect(authorSlugs).toContain(teamCatalog.slug); // Other user can only see org const otherItems = await InternalMcpCatalogModel.findAll({ @@ -267,8 +270,8 @@ test("findAll with scope filtering returns correct items", async ({ userId: otherUser.id, isAdmin: false, }); - const otherNames = otherItems.map((i) => i.name); - expect(otherNames).toContain(orgCatalog.name); - expect(otherNames).not.toContain(personalCatalog.name); - expect(otherNames).not.toContain(teamCatalog.name); + const otherSlugs = otherItems.map((i) => i.slug); + expect(otherSlugs).toContain(orgCatalog.slug); + expect(otherSlugs).not.toContain(personalCatalog.slug); + expect(otherSlugs).not.toContain(teamCatalog.slug); }); diff --git a/platform/backend/src/models/mcp-server-installation-request.ts b/platform/backend/src/models/mcp-server-installation-request.ts index 1af3906388..51707732f0 100644 --- a/platform/backend/src/models/mcp-server-installation-request.ts +++ b/platform/backend/src/models/mcp-server-installation-request.ts @@ -163,7 +163,8 @@ class McpServerInstallationRequestModel { // Create internal catalog item from external server data await InternalMcpCatalogModel.create({ - name: externalServer.display_name || externalServer.name, + slug: externalServer.name, + displayName: externalServer.display_name || externalServer.name, version: undefined, instructions: externalServer.instructions, serverType: externalServer.server.type, @@ -185,7 +186,8 @@ class McpServerInstallationRequestModel { if (customConfig.type === "remote") { await InternalMcpCatalogModel.create({ - name: customConfig.name, + slug: customConfig.name, + displayName: customConfig.name, version: customConfig.version, serverType: "remote", serverUrl: customConfig.serverUrl, @@ -195,7 +197,8 @@ class McpServerInstallationRequestModel { }); } else if (customConfig.type === "local") { await InternalMcpCatalogModel.create({ - name: customConfig.name, + slug: customConfig.name, + displayName: customConfig.name, version: customConfig.version, serverType: "local", localConfig: customConfig.localConfig, diff --git a/platform/backend/src/models/mcp-server.test.ts b/platform/backend/src/models/mcp-server.test.ts index d8b25b738b..992853bef7 100644 --- a/platform/backend/src/models/mcp-server.test.ts +++ b/platform/backend/src/models/mcp-server.test.ts @@ -10,19 +10,22 @@ describe("McpServerModel", () => { }) => { // Create catalogs for each server type const localCatalog = await makeInternalMcpCatalog({ - name: "Local Test Catalog", + slug: "Local Test Catalog", + displayName: "Local Test Catalog", serverType: "local", localConfig: { command: "node", arguments: ["server.js"] }, }); const remoteCatalog = await makeInternalMcpCatalog({ - name: "Remote Test Catalog", + slug: "Remote Test Catalog", + displayName: "Remote Test Catalog", serverType: "remote", serverUrl: "https://example.com/mcp", }); const builtinCatalog = await makeInternalMcpCatalog({ - name: "Builtin Test Catalog", + slug: "Builtin Test Catalog", + displayName: "Builtin Test Catalog", serverType: "builtin", }); diff --git a/platform/backend/src/models/mcp-server.ts b/platform/backend/src/models/mcp-server.ts index b26b5b858e..76fa4c1522 100644 --- a/platform/backend/src/models/mcp-server.ts +++ b/platform/backend/src/models/mcp-server.ts @@ -122,7 +122,7 @@ class McpServerModel { .select({ server: schema.mcpServersTable, ownerEmail: schema.usersTable.email, - catalogName: schema.internalMcpCatalogTable.name, + catalogSlug: schema.internalMcpCatalogTable.slug, teamName: schema.teamsTable.name, secretIsVault: schema.secretsTable.isVault, secretIsByosVault: schema.secretsTable.isByosVault, @@ -205,7 +205,7 @@ class McpServerModel { serversMap.set(row.server.id, { ...row.server, ownerEmail: row.ownerEmail, - catalogName: row.catalogName, + catalogSlug: row.catalogSlug, users: [], userDetails: [], teamDetails, diff --git a/platform/backend/src/models/tool-archestra-assignment.test.ts b/platform/backend/src/models/tool-archestra-assignment.test.ts index 3cff169b61..3a5c9695fd 100644 --- a/platform/backend/src/models/tool-archestra-assignment.test.ts +++ b/platform/backend/src/models/tool-archestra-assignment.test.ts @@ -90,7 +90,8 @@ describe("Archestra Tools Dynamic Assignment", () => { // Create an MCP server tool const catalogItem = await makeInternalMcpCatalog({ - name: "test-mcp-server", + slug: "test-mcp-server", + displayName: "test-mcp-server", serverUrl: "https://test.com/mcp/", }); diff --git a/platform/backend/src/models/tool.test.ts b/platform/backend/src/models/tool.test.ts index 2ed1725e62..5e1e70cff9 100644 --- a/platform/backend/src/models/tool.test.ts +++ b/platform/backend/src/models/tool.test.ts @@ -382,7 +382,8 @@ describe("ToolModel", () => { const agent = await makeAgent(); const catalogItem = await makeInternalMcpCatalog({ - name: "github-mcp-server", + slug: "github-mcp-server", + displayName: "github-mcp-server", serverUrl: "https://api.githubcopilot.com/mcp/", }); @@ -422,7 +423,7 @@ describe("ToolModel", () => { credentialSourceMcpServerId: null, executionSourceMcpServerId: null, catalogId: catalogItem.id, - catalogName: "github-mcp-server", + catalogSlug: "github-mcp-server", useDynamicTeamCredential: false, }); }); @@ -438,7 +439,8 @@ describe("ToolModel", () => { const agent = await makeAgent(); const catalogItem = await makeInternalMcpCatalog({ - name: "github-mcp-server", + slug: "github-mcp-server", + displayName: "github-mcp-server", serverUrl: "https://api.githubcopilot.com/mcp/", }); @@ -491,7 +493,8 @@ describe("ToolModel", () => { // Create an MCP server and tool const catalogItem = await makeInternalMcpCatalog({ - name: "github-mcp-server", + slug: "github-mcp-server", + displayName: "github-mcp-server", serverUrl: "https://api.githubcopilot.com/mcp/", }); await makeMcpServer({ @@ -532,7 +535,8 @@ describe("ToolModel", () => { // Create an MCP server const catalogItem = await makeInternalMcpCatalog({ - name: "github-mcp-server", + slug: "github-mcp-server", + displayName: "github-mcp-server", serverUrl: "https://api.githubcopilot.com/mcp/", }); await makeMcpServer({ @@ -582,7 +586,8 @@ describe("ToolModel", () => { // Create two MCP servers const catalogItem = await makeInternalMcpCatalog({ - name: "github-mcp-server", + slug: "github-mcp-server", + displayName: "github-mcp-server", serverUrl: "https://api.githubcopilot.com/mcp/", }); await makeMcpServer({ @@ -592,7 +597,8 @@ describe("ToolModel", () => { }); const catalogItem2 = await makeInternalMcpCatalog({ - name: "other-mcp-server", + slug: "other-mcp-server", + displayName: "other-mcp-server", serverUrl: "https://api.othercopilot.com/mcp/", }); await makeMcpServer({ @@ -687,7 +693,8 @@ describe("ToolModel", () => { const agent2 = await makeAgent({ name: "Agent 2" }); const catalogItem = await makeInternalMcpCatalog({ - name: "shared-catalog", + slug: "shared-catalog", + displayName: "shared-catalog", serverUrl: "https://api.shared.com/mcp/", }); @@ -748,7 +755,8 @@ describe("ToolModel", () => { makeInternalMcpCatalog, }) => { const catalogItem = await makeInternalMcpCatalog({ - name: "empty-catalog", + slug: "empty-catalog", + displayName: "empty-catalog", serverUrl: "https://api.empty.com/mcp/", }); @@ -1031,8 +1039,14 @@ describe("ToolModel", () => { makeInternalMcpCatalog, makeTool, }) => { - const catalog1 = await makeInternalMcpCatalog({ name: "Catalog 1" }); - const catalog2 = await makeInternalMcpCatalog({ name: "Catalog 2" }); + const catalog1 = await makeInternalMcpCatalog({ + slug: "catalog-1", + displayName: "Catalog 1", + }); + const catalog2 = await makeInternalMcpCatalog({ + slug: "catalog-2", + displayName: "Catalog 2", + }); // Create a tool that already belongs to catalog1 const existingTool = await makeTool({ @@ -1786,7 +1800,8 @@ describe("ToolModel", () => { makeAgent, }) => { const catalog = await makeInternalMcpCatalog({ - name: "old-catalog-name", + slug: "old-catalog-name", + displayName: "old-catalog-name", }); await makeMcpServer({ catalogId: catalog.id }); const agent = await makeAgent(); diff --git a/platform/backend/src/models/tool.ts b/platform/backend/src/models/tool.ts index 08d5f8b92c..b76a1d3a98 100644 --- a/platform/backend/src/models/tool.ts +++ b/platform/backend/src/models/tool.ts @@ -309,7 +309,7 @@ class ToolModel { }, catalog: { id: schema.internalMcpCatalogTable.id, - name: schema.internalMcpCatalogTable.name, + slug: schema.internalMcpCatalogTable.slug, }, }) .from(schema.toolsTable) @@ -583,7 +583,8 @@ class ToolModel { .insert(schema.internalMcpCatalogTable) .values({ id: catalogId, - name: "Archestra", + slug: "Archestra", + displayName: "Archestra", description: "Built-in Archestra tools for managing profiles, limits, policies, and MCP servers.", serverType: "builtin", @@ -742,7 +743,7 @@ class ToolModel { executionSourceMcpServerId: string | null; useDynamicTeamCredential: boolean; catalogId: string | null; - catalogName: string | null; + catalogSlug: string | null; }> > { if (toolNames.length === 0) { @@ -761,7 +762,7 @@ class ToolModel { useDynamicTeamCredential: schema.agentToolsTable.useDynamicTeamCredential, catalogId: schema.toolsTable.catalogId, - catalogName: schema.internalMcpCatalogTable.name, + catalogSlug: schema.internalMcpCatalogTable.slug, }) .from(schema.toolsTable) .innerJoin( diff --git a/platform/backend/src/routes/internal-mcp-catalog.env.test.ts b/platform/backend/src/routes/internal-mcp-catalog.env.test.ts index 831c4e5a62..c095becf47 100644 --- a/platform/backend/src/routes/internal-mcp-catalog.env.test.ts +++ b/platform/backend/src/routes/internal-mcp-catalog.env.test.ts @@ -12,7 +12,8 @@ describe("Internal MCP Catalog - Environment Variables", () => { describe("CREATE - Environment Variable Handling", () => { test("1.1 creates catalog with plain_text env vars", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "test-plain-text-env", + slug: "test-plain-text-env", + displayName: "Test Plain Text Env", serverType: "local", localConfig: { command: "npx", @@ -60,7 +61,8 @@ describe("Internal MCP Catalog - Environment Variables", () => { }); const catalog = await InternalMcpCatalogModel.create({ - name: "test-secret-env", + slug: "test-secret-env", + displayName: "Test Secret Env", serverType: "local", localConfigSecretId: envSecret.id, localConfig: { @@ -96,7 +98,8 @@ describe("Internal MCP Catalog - Environment Variables", () => { test("1.3 creates catalog with prompted secret env vars", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "test-prompted-secret", + slug: "test-prompted-secret", + displayName: "Test Prompted Secret", serverType: "local", localConfig: { command: "npx", @@ -147,7 +150,8 @@ describe("Internal MCP Catalog - Environment Variables", () => { }); const catalog = await InternalMcpCatalogModel.create({ - name: "test-yaml-env", + slug: "test-yaml-env", + displayName: "Test YAML Env", serverType: "local", deploymentSpecYaml: yamlTemplate, localConfig: { @@ -199,7 +203,8 @@ describe("Internal MCP Catalog - Environment Variables", () => { test("2.1 adds new plain_text env var to existing catalog", async () => { // Create catalog with one env var const catalog = await InternalMcpCatalogModel.create({ - name: "test-add-env", + slug: "test-add-env", + displayName: "Test Add Env", serverType: "local", localConfig: { command: "npx", @@ -247,7 +252,8 @@ describe("Internal MCP Catalog - Environment Variables", () => { test("2.2 adds new secret env var to existing catalog", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "test-add-secret-env", + slug: "test-add-secret-env", + displayName: "Test Add Secret Env", serverType: "local", localConfig: { command: "npx", @@ -316,7 +322,8 @@ describe("Internal MCP Catalog - Environment Variables", () => { }); const catalog = await InternalMcpCatalogModel.create({ - name: "test-remove-env", + slug: "test-remove-env", + displayName: "Test Remove Env", serverType: "local", deploymentSpecYaml: yamlTemplate, localConfig: { @@ -707,7 +714,8 @@ spec: describe("Edge Cases", () => { test("handles empty environment array", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "test-empty-env", + slug: "test-empty-env", + displayName: "Test Empty Env", serverType: "local", localConfig: { command: "npx", @@ -721,7 +729,8 @@ spec: test("handles undefined environment", async () => { const catalog = await InternalMcpCatalogModel.create({ - name: "test-undefined-env", + slug: "test-undefined-env", + displayName: "Test Undefined Env", serverType: "local", localConfig: { command: "npx", diff --git a/platform/backend/src/routes/internal-mcp-catalog.ts b/platform/backend/src/routes/internal-mcp-catalog.ts index b7f23be971..dde8273cc6 100644 --- a/platform/backend/src/routes/internal-mcp-catalog.ts +++ b/platform/backend/src/routes/internal-mcp-catalog.ts @@ -142,7 +142,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { const vaultReference = `${oauthClientSecretVaultPath}#${oauthClientSecretVaultKey}`; const secret = await secretManager().createSecret( { client_secret: vaultReference }, - `${restBody.name}-oauth-client-secret-vault`, + `${restBody.slug}-oauth-client-secret-vault`, ); clientSecretId = secret.id; restBody.clientSecretId = clientSecretId; @@ -163,7 +163,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { const clientSecret = restBody.oauthConfig.client_secret; const secret = await secretManager().createSecret( { client_secret: clientSecret }, - `${restBody.name}-oauth-client-secret`, + `${restBody.slug}-oauth-client-secret`, ); clientSecretId = secret.id; @@ -187,7 +187,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { const vaultReference = `${localConfigVaultPath}#${localConfigVaultKey}`; const secret = await secretManager().createSecret( { [localConfigVaultKey]: vaultReference }, - `${restBody.name}-local-config-env-vault`, + `${restBody.slug}-local-config-env-vault`, ); localConfigSecretId = secret.id; restBody.localConfigSecretId = localConfigSecretId; @@ -240,7 +240,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { if (Object.keys(secretEnvVars).length > 0) { const secret = await secretManager().createSecret( secretEnvVars, - `${restBody.name}-local-config-env`, + `${restBody.slug}-local-config-env`, ); localConfigSecretId = secret.id; restBody.localConfigSecretId = localConfigSecretId; @@ -356,8 +356,9 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { } // Prevent renaming the Playwright catalog item - if (isPlaywrightCatalogItem(id) && body.name !== undefined) { - delete body.name; + if (isPlaywrightCatalogItem(id)) { + if (body.slug !== undefined) delete body.slug; + if (body.displayName !== undefined) delete body.displayName; } const { @@ -428,7 +429,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { const vaultReference = `${oauthClientSecretVaultPath}#${oauthClientSecretVaultKey}`; const secret = await secretManager().createSecret( { client_secret: vaultReference }, - `${originalCatalogItem.name}-oauth-client-secret-vault`, + `${originalCatalogItem.slug}-oauth-client-secret-vault`, ); clientSecretId = secret.id; restBody.clientSecretId = clientSecretId; @@ -456,7 +457,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { // Create new secret const secret = await secretManager().createSecret( { client_secret: clientSecret }, - `${originalCatalogItem.name}-oauth-client-secret`, + `${originalCatalogItem.slug}-oauth-client-secret`, ); clientSecretId = secret.id; } @@ -485,7 +486,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { const vaultReference = `${localConfigVaultPath}#${localConfigVaultKey}`; const secret = await secretManager().createSecret( { [localConfigVaultKey]: vaultReference }, - `${originalCatalogItem.name}-local-config-env-vault`, + `${originalCatalogItem.slug}-local-config-env-vault`, ); localConfigSecretId = secret.id; restBody.localConfigSecretId = localConfigSecretId; @@ -569,7 +570,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { // Create new secret const secret = await secretManager().createSecret( secretEnvVars, - `${originalCatalogItem.name}-local-config-env`, + `${originalCatalogItem.slug}-local-config-env`, ); localConfigSecretId = secret.id; } @@ -746,24 +747,24 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { ); fastify.delete( - "/api/internal_mcp_catalog/by-name/:name", + "/api/internal_mcp_catalog/by-slug/:slug", { schema: { - operationId: RouteId.DeleteInternalMcpCatalogItemByName, - description: "Delete an Internal MCP catalog item by name", + operationId: RouteId.DeleteInternalMcpCatalogItemBySlug, + description: "Delete an Internal MCP catalog item by slug", tags: ["MCP Catalog"], params: z.object({ - name: z.string().min(1), + slug: z.string().min(1), }), response: constructResponseSchema(DeleteObjectResponseSchema), }, }, async (request, reply) => { - const { name } = request.params; - const catalogItem = await InternalMcpCatalogModel.findByName(name); + const { slug } = request.params; + const catalogItem = await InternalMcpCatalogModel.findBySlug(slug); if (!catalogItem) { - throw new ApiError(404, `Catalog item with name "${name}" not found`); + throw new ApiError(404, `Catalog item with slug "${slug}" not found`); } if (isBuiltInCatalogId(catalogItem.id)) { @@ -856,7 +857,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { // Generate a default YAML template const yamlTemplate = generateDeploymentYamlTemplate({ serverId: "{server_id}", - serverName: catalogItem.name, + serverName: catalogItem.slug, namespace: config.orchestrator.kubernetes.namespace, dockerImage: catalogItem.localConfig?.dockerImage || @@ -932,7 +933,7 @@ const internalMcpCatalogRoutes: FastifyPluginAsyncZod = async (fastify) => { // Generate and return a fresh default YAML template const yamlTemplate = generateDeploymentYamlTemplate({ serverId: "{server_id}", - serverName: catalogItem.name, + serverName: catalogItem.slug, namespace: config.orchestrator.kubernetes.namespace, dockerImage: catalogItem.localConfig?.dockerImage || diff --git a/platform/backend/src/routes/mcp-server.ts b/platform/backend/src/routes/mcp-server.ts index 52167f397b..bd16c3142a 100644 --- a/platform/backend/src/routes/mcp-server.ts +++ b/platform/backend/src/routes/mcp-server.ts @@ -507,7 +507,7 @@ const mcpServerRoutes: FastifyPluginAsyncZod = async (fastify) => { try { // Capture catalogId before async callback to ensure it's available const capturedCatalogId = catalogItem.id; - const capturedCatalogName = catalogItem.name; + const capturedCatalogSlug = catalogItem.slug; // Set status to pending before starting the deployment await McpServerModel.update(mcpServer.id, { @@ -566,7 +566,7 @@ const mcpServerRoutes: FastifyPluginAsyncZod = async (fastify) => { // Persist tools in the database // Use catalog item name (without userId) for tool naming to avoid duplicates across users - const toolNamePrefix = capturedCatalogName || mcpServer.name; + const toolNamePrefix = capturedCatalogSlug || mcpServer.name; const toolsToCreate = tools.map((tool) => ({ name: ToolModel.slugifyName(toolNamePrefix, tool.name), description: tool.description, diff --git a/platform/backend/src/routes/oauth.ts b/platform/backend/src/routes/oauth.ts index 0a8c049c8f..3af28fb7d2 100644 --- a/platform/backend/src/routes/oauth.ts +++ b/platform/backend/src/routes/oauth.ts @@ -637,7 +637,7 @@ const oauthRoutes: FastifyPluginAsyncZod = async (fastify) => { "Attempting dynamic client registration", ); registrationResult = await registerOAuthClient(registrationEndpoint, { - client_name: `Archestra Platform - ${catalogItem.name}`, + client_name: `Archestra Platform - ${catalogItem.displayName}`, redirect_uris: [redirectUri], grant_types: ["authorization_code", "refresh_token"], response_types: ["code"], @@ -913,14 +913,14 @@ const oauthRoutes: FastifyPluginAsyncZod = async (fastify) => { const secret = await secretManager().createSecret( secretPayload, - `${catalogItem.name}-oauth`, + `${catalogItem.slug}-oauth`, isByosEnabled(), // forceDB: store in DB when BYOS is enabled ); return reply.send({ success: true, catalogId: oauthState.catalogId, - name: catalogItem.name, + name: catalogItem.slug, accessToken: tokenData.access_token, // Only include optional fields if they have truthy values (avoid null which fails schema validation) ...(tokenData.refresh_token && { diff --git a/platform/backend/src/services/mcp-reinstall.test.ts b/platform/backend/src/services/mcp-reinstall.test.ts index ff0272725e..874a4b58fb 100644 --- a/platform/backend/src/services/mcp-reinstall.test.ts +++ b/platform/backend/src/services/mcp-reinstall.test.ts @@ -47,7 +47,8 @@ describe("mcp-reinstall", () => { ): InternalMcpCatalog => ({ id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "local", localConfig: { command: "npm", @@ -63,7 +64,8 @@ describe("mcp-reinstall", () => { ): InternalMcpCatalog => ({ id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "remote", userConfig, oauthConfig, @@ -213,11 +215,11 @@ describe("mcp-reinstall", () => { test("returns true when server NAME changes (even with no prompted env vars)", () => { const oldConfig = { ...createLocalCatalog([]), - name: "Old Server Name", + slug: "Old Server Name", }; const newConfig = { ...createLocalCatalog([]), - name: "New Server Name", + slug: "New Server Name", }; const result = requiresNewUserInputForReinstall(oldConfig, newConfig); @@ -235,11 +237,11 @@ describe("mcp-reinstall", () => { ]; const oldConfig = { ...createLocalCatalog(envVars), - name: "Old Server Name", + slug: "Old Server Name", }; const newConfig = { ...createLocalCatalog(envVars), - name: "New Server Name", + slug: "New Server Name", }; const result = requiresNewUserInputForReinstall(oldConfig, newConfig); @@ -336,13 +338,15 @@ describe("mcp-reinstall", () => { test("handles missing localConfig.environment gracefully", () => { const oldConfig = { id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "local", localConfig: {}, } as InternalMcpCatalog; const newConfig = { id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "local", localConfig: {}, } as InternalMcpCatalog; @@ -355,13 +359,15 @@ describe("mcp-reinstall", () => { test("handles null localConfig gracefully", () => { const oldConfig = { id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "local", localConfig: null, } as InternalMcpCatalog; const newConfig = { id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "local", localConfig: null, } as InternalMcpCatalog; @@ -394,8 +400,8 @@ describe("mcp-reinstall", () => { }); test("returns false when only name changes (no auth config)", () => { - const oldConfig = { ...createRemoteCatalog({}), name: "Old Name" }; - const newConfig = { ...createRemoteCatalog({}), name: "New Name" }; + const oldConfig = { ...createRemoteCatalog({}), slug: "Old Name" }; + const newConfig = { ...createRemoteCatalog({}), slug: "New Name" }; const result = requiresNewUserInputForReinstall(oldConfig, newConfig); @@ -406,11 +412,11 @@ describe("mcp-reinstall", () => { const oauthConfig = { authorizationUrl: "https://example.com/auth" }; const oldConfig = { ...createRemoteCatalog({}, oauthConfig), - name: "Old Name", + slug: "Old Name", }; const newConfig = { ...createRemoteCatalog({}, oauthConfig), - name: "New Name", + slug: "New Name", }; const result = requiresNewUserInputForReinstall(oldConfig, newConfig); @@ -420,8 +426,8 @@ describe("mcp-reinstall", () => { test("returns false when only name changes (with existing required userConfig)", () => { const config = { field: { type: "string", required: true } }; - const oldConfig = { ...createRemoteCatalog(config), name: "Old Name" }; - const newConfig = { ...createRemoteCatalog(config), name: "New Name" }; + const oldConfig = { ...createRemoteCatalog(config), slug: "Old Name" }; + const newConfig = { ...createRemoteCatalog(config), slug: "New Name" }; const result = requiresNewUserInputForReinstall(oldConfig, newConfig); @@ -524,14 +530,16 @@ describe("mcp-reinstall", () => { test("handles null userConfig gracefully", () => { const oldConfig = { id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "remote", userConfig: null, oauthConfig: null, } as InternalMcpCatalog; const newConfig = { id: "test-id", - name: "Test Server", + slug: "Test Server", + displayName: "Test Server", serverType: "remote", userConfig: null, oauthConfig: null, @@ -573,7 +581,8 @@ describe("mcp-reinstall", () => { ): InternalMcpCatalog => ({ id: "catalog-123", - name: "Test Catalog", + slug: "Test Catalog", + displayName: "Test Catalog", serverType: "local", localConfig: { command: "npm", @@ -690,7 +699,8 @@ describe("mcp-reinstall", () => { }); const catalog = createCatalog({ serverType: "remote", - name: "New Catalog Name", + slug: "New Catalog Name", + displayName: "New Catalog Name", }); vi.mocked(McpServerModel.getToolsFromServer).mockResolvedValue([ @@ -723,7 +733,8 @@ describe("mcp-reinstall", () => { }); const catalog = createCatalog({ serverType: "local", - name: "microsoft__playwright-mcp", + slug: "microsoft__playwright-mcp", + displayName: "microsoft__playwright-mcp", }); vi.mocked(McpServerRuntimeManager.restartServer).mockResolvedValue( @@ -760,7 +771,8 @@ describe("mcp-reinstall", () => { }); const catalog = createCatalog({ serverType: "local", - name: "new-catalog-name", + slug: "new-catalog-name", + displayName: "new-catalog-name", }); vi.mocked(McpServerRuntimeManager.restartServer).mockResolvedValue( @@ -801,7 +813,8 @@ describe("mcp-reinstall", () => { }); const catalog = createCatalog({ serverType: "local", - name: "new-name", + slug: "new-name", + displayName: "new-name", }); vi.mocked(McpServerRuntimeManager.restartServer).mockResolvedValue( @@ -836,7 +849,8 @@ describe("mcp-reinstall", () => { }); const catalog = createCatalog({ serverType: "local", - name: "microsoft__playwright-mcp", + slug: "microsoft__playwright-mcp", + displayName: "microsoft__playwright-mcp", }); vi.mocked(McpServerRuntimeManager.restartServer).mockResolvedValue( diff --git a/platform/backend/src/services/mcp-reinstall.ts b/platform/backend/src/services/mcp-reinstall.ts index 1e1e0ed44f..c950b18fea 100644 --- a/platform/backend/src/services/mcp-reinstall.ts +++ b/platform/backend/src/services/mcp-reinstall.ts @@ -27,13 +27,13 @@ export function requiresNewUserInputForReinstall( oldCatalogItem: InternalMcpCatalog, newCatalogItem: InternalMcpCatalog, ): boolean { - // Local servers: check if name or prompted env vars changed + // Local servers: check if slug or prompted env vars changed if (newCatalogItem.serverType === "local") { - // 1. Check if name changed - affects secret paths - if (oldCatalogItem.name !== newCatalogItem.name) { + // 1. Check if slug changed - affects K8s deployment names and secret paths + if (oldCatalogItem.slug !== newCatalogItem.slug) { logger.info( { catalogId: newCatalogItem.id }, - "Catalog name changed - manual reinstall required", + "Catalog slug changed - manual reinstall required", ); return true; } @@ -103,9 +103,9 @@ export async function autoReinstallServer( "Starting auto-reinstall of MCP server", ); - // Reconstruct the correct server name from the current catalog name. + // Reconstruct the correct server name from the current catalog slug. const reconstructedName = McpServerModel.constructServerName({ - baseName: catalogItem.name, + baseName: catalogItem.slug, serverType: server.serverType, ownerId: server.ownerId, teamId: server.teamId, @@ -141,8 +141,8 @@ export async function autoReinstallServer( // Fetch and sync tools const tools = await McpServerModel.getToolsFromServer(server); - // Use catalog item name for tool naming (consistent with install flow) - const toolNamePrefix = catalogItem.name; + // Use catalog item slug for tool naming (consistent with install flow) + const toolNamePrefix = catalogItem.slug; const toolsToSync = tools.map((tool) => ({ name: ToolModel.slugifyName(toolNamePrefix, tool.name), description: tool.description, diff --git a/platform/backend/src/test/fixtures.ts b/platform/backend/src/test/fixtures.ts index cc27817cb3..75cbca0a68 100644 --- a/platform/backend/src/test/fixtures.ts +++ b/platform/backend/src/test/fixtures.ts @@ -415,7 +415,8 @@ async function makeInternalMcpCatalog( Pick< InsertInternalMcpCatalog, | "id" - | "name" + | "slug" + | "displayName" | "serverType" | "serverUrl" | "description" @@ -447,7 +448,8 @@ async function makeInternalMcpCatalog( return await InternalMcpCatalogModel.create( { - name: `test-catalog-${crypto.randomUUID().substring(0, 8)}`, + slug: `test-catalog-${crypto.randomUUID().substring(0, 8)}`, + displayName: "Test Catalog", serverType: "remote", serverUrl: "https://api.example.com/mcp/", scope: "org", @@ -936,7 +938,8 @@ async function seedAndAssignArchestraTools(agentId: string): Promise { if (!existing) { await db.insert(schema.internalMcpCatalogTable).values({ id: ARCHESTRA_MCP_CATALOG_ID, - name: "Archestra", + slug: "Archestra", + displayName: "Archestra", description: "Built-in Archestra tools for managing profiles, limits, policies, and MCP servers.", serverType: "builtin", diff --git a/platform/backend/src/types/mcp-catalog.ts b/platform/backend/src/types/mcp-catalog.ts index f094c7a5bf..c99743eca6 100644 --- a/platform/backend/src/types/mcp-catalog.ts +++ b/platform/backend/src/types/mcp-catalog.ts @@ -108,7 +108,8 @@ export const InsertInternalMcpCatalogSchema = createInsertSchema( .extend({ // Allow explicit ID for builtin catalog items (e.g., Archestra) id: z.string().uuid().optional(), - name: z.string().trim().min(1, "Name cannot be empty"), + slug: z.string().trim().min(1, "Slug cannot be empty"), + displayName: z.string().trim().min(1, "Display name cannot be empty"), serverType: InternalMcpCatalogServerTypeSchema, authFields: z.array(AuthFieldSchema).nullable().optional(), userConfig: z @@ -133,7 +134,8 @@ export const UpdateInternalMcpCatalogSchema = createUpdateSchema( schema.internalMcpCatalogTable, ) .extend({ - name: z.string().trim().min(1, "Name cannot be empty"), + slug: z.string().trim().min(1, "Slug cannot be empty"), + displayName: z.string().trim().min(1, "Display name cannot be empty"), serverType: InternalMcpCatalogServerTypeSchema, authFields: z.array(AuthFieldSchema).nullable().optional(), userConfig: z diff --git a/platform/backend/src/types/mcp-server.ts b/platform/backend/src/types/mcp-server.ts index 165b91a4ea..410baccdda 100644 --- a/platform/backend/src/types/mcp-server.ts +++ b/platform/backend/src/types/mcp-server.ts @@ -29,7 +29,7 @@ export const SelectMcpServerSchema = createSelectSchema( ).extend({ serverType: InternalMcpCatalogServerTypeSchema, ownerEmail: z.string().nullable().optional(), - catalogName: z.string().nullable().optional(), + catalogSlug: z.string().nullable().optional(), users: z.array(z.string()).optional(), userDetails: z .array( diff --git a/platform/backend/src/types/tool.ts b/platform/backend/src/types/tool.ts index ec76f9b5c4..ebeb53bf63 100644 --- a/platform/backend/src/types/tool.ts +++ b/platform/backend/src/types/tool.ts @@ -34,7 +34,7 @@ export const ExtendedSelectToolSchema = SelectToolSchema.omit({ catalog: z .object({ id: z.string(), - name: z.string(), + slug: z.string(), }) .nullable(), }); diff --git a/platform/e2e-tests/tests/api/built-in-agents.spec.ts b/platform/e2e-tests/tests/api/built-in-agents.spec.ts index 38e7c04c75..46e1e6cdb8 100644 --- a/platform/e2e-tests/tests/api/built-in-agents.spec.ts +++ b/platform/e2e-tests/tests/api/built-in-agents.spec.ts @@ -203,7 +203,8 @@ test.describe("Built-In Agents API", () => { const serverName = `auto-config-route-test-${Date.now()}`; const catalogResponse = await createMcpCatalogItem(request, { - name: serverName, + slug: serverName, + displayName: serverName, description: "Test server for auto-configure route e2e test", serverType: "remote", serverUrl: `${WIREMOCK_INTERNAL_URL}/mcp/context7`, @@ -211,7 +212,7 @@ test.describe("Built-In Agents API", () => { const catalogItem = await catalogResponse.json(); const serverResponse = await installMcpServer(request, { - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, teamId: defaultTeam?.id, }); @@ -330,7 +331,8 @@ test.describe("Built-In Agents API", () => { const serverName = `policy-config-assign-test-${Date.now()}`; const catalogResponse = await createMcpCatalogItem(request, { - name: serverName, + slug: serverName, + displayName: serverName, description: "Test server for auto-configure assignment e2e test", serverType: "remote", serverUrl: `${WIREMOCK_INTERNAL_URL}/mcp/context7`, @@ -341,7 +343,7 @@ test.describe("Built-In Agents API", () => { try { // 3. Install MCP server WITHOUT agentIds — tools are created but not assigned const serverResponse = await installMcpServer(request, { - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, teamId: defaultTeam?.id, }); diff --git a/platform/e2e-tests/tests/api/custom-yaml-restart.spec.ts b/platform/e2e-tests/tests/api/custom-yaml-restart.spec.ts index 78e890bc9a..a3aa504e87 100644 --- a/platform/e2e-tests/tests/api/custom-yaml-restart.spec.ts +++ b/platform/e2e-tests/tests/api/custom-yaml-restart.spec.ts @@ -29,7 +29,8 @@ test.describe("Custom YAML Spec - Server Restart on YAML Edit", () => { // STEP 1: Create catalog item (same config as internal-dev-test-server) // ======================================== const catalogResponse = await createMcpCatalogItem(request, { - name: serverName, + slug: serverName, + displayName: serverName, description: "Test custom YAML restart", serverType: "local", localConfig: { diff --git a/platform/e2e-tests/tests/api/fixtures.ts b/platform/e2e-tests/tests/api/fixtures.ts index cf73fdc321..74acb4acd1 100644 --- a/platform/e2e-tests/tests/api/fixtures.ts +++ b/platform/e2e-tests/tests/api/fixtures.ts @@ -350,7 +350,8 @@ const deleteTrustedDataPolicy = async ( const createMcpCatalogItem = async ( request: APIRequestContext, catalogItem: { - name: string; + slug: string; + displayName: string; description: string; serverType: "local" | "remote"; localConfig?: unknown; diff --git a/platform/e2e-tests/tests/api/image-pull-secrets.spec.ts b/platform/e2e-tests/tests/api/image-pull-secrets.spec.ts index c4774bf71e..998c9d6831 100644 --- a/platform/e2e-tests/tests/api/image-pull-secrets.spec.ts +++ b/platform/e2e-tests/tests/api/image-pull-secrets.spec.ts @@ -103,7 +103,8 @@ test.describe("Image Pull Secrets", () => { }) => { // Create a catalog item with both "existing" and "credentials" image pull secrets const catalogResponse = await createMcpCatalogItem(request, { - name: `e2e-ips-test-${Date.now()}`, + slug: `e2e-ips-test-${Date.now()}`, + displayName: `e2e-ips-test-${Date.now()}`, description: "E2E test for image pull secrets", serverType: "local", localConfig: { diff --git a/platform/e2e-tests/tests/api/mcp-catalog-labels.spec.ts b/platform/e2e-tests/tests/api/mcp-catalog-labels.spec.ts index f4ba7783c6..c158ab654f 100644 --- a/platform/e2e-tests/tests/api/mcp-catalog-labels.spec.ts +++ b/platform/e2e-tests/tests/api/mcp-catalog-labels.spec.ts @@ -7,7 +7,8 @@ test.describe("MCP Catalog Labels", () => { deleteMcpCatalogItem, }) => { const response = await createMcpCatalogItem(request, { - name: `label-test-${Date.now()}`, + slug: `label-test-${Date.now()}`, + displayName: `label-test-${Date.now()}`, description: "Test catalog item with labels", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -36,7 +37,8 @@ test.describe("MCP Catalog Labels", () => { deleteMcpCatalogItem, }) => { const createResponse = await createMcpCatalogItem(request, { - name: `label-get-test-${Date.now()}`, + slug: `label-get-test-${Date.now()}`, + displayName: `label-get-test-${Date.now()}`, description: "Test get with labels", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -67,7 +69,8 @@ test.describe("MCP Catalog Labels", () => { deleteMcpCatalogItem, }) => { const createResponse = await createMcpCatalogItem(request, { - name: `label-update-test-${Date.now()}`, + slug: `label-update-test-${Date.now()}`, + displayName: `label-update-test-${Date.now()}`, description: "Test label update", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -109,7 +112,8 @@ test.describe("MCP Catalog Labels", () => { deleteMcpCatalogItem, }) => { const createResponse = await createMcpCatalogItem(request, { - name: `label-remove-test-${Date.now()}`, + slug: `label-remove-test-${Date.now()}`, + displayName: `label-remove-test-${Date.now()}`, description: "Test label removal", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -146,7 +150,8 @@ test.describe("MCP Catalog Labels", () => { deleteMcpCatalogItem, }) => { const createResponse = await createMcpCatalogItem(request, { - name: `label-list-test-${Date.now()}`, + slug: `label-list-test-${Date.now()}`, + displayName: `label-list-test-${Date.now()}`, description: "Test labels in list", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -181,7 +186,8 @@ test.describe("MCP Catalog Labels", () => { deleteMcpCatalogItem, }) => { const createResponse = await createMcpCatalogItem(request, { - name: `label-keys-test-${Date.now()}`, + slug: `label-keys-test-${Date.now()}`, + displayName: `label-keys-test-${Date.now()}`, description: "Test label keys endpoint", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -215,7 +221,8 @@ test.describe("MCP Catalog Labels", () => { }) => { const ts = Date.now(); const createResponse1 = await createMcpCatalogItem(request, { - name: `label-values-test-1-${ts}`, + slug: `label-values-test-1-${ts}`, + displayName: `label-values-test-1-${ts}`, description: "Test label values endpoint", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -223,7 +230,8 @@ test.describe("MCP Catalog Labels", () => { }); const createResponse2 = await createMcpCatalogItem(request, { - name: `label-values-test-2-${ts}`, + slug: `label-values-test-2-${ts}`, + displayName: `label-values-test-2-${ts}`, description: "Test label values endpoint", serverType: "remote", serverUrl: "https://example.com/mcp", @@ -255,7 +263,8 @@ test.describe("MCP Catalog Labels", () => { deleteMcpCatalogItem, }) => { const createResponse = await createMcpCatalogItem(request, { - name: `label-cascade-test-${Date.now()}`, + slug: `label-cascade-test-${Date.now()}`, + displayName: `label-cascade-test-${Date.now()}`, description: "Test cascade delete", serverType: "remote", serverUrl: "https://example.com/mcp", diff --git a/platform/e2e-tests/tests/api/mcp-gateway-auth-at-call-time.spec.ts b/platform/e2e-tests/tests/api/mcp-gateway-auth-at-call-time.spec.ts index ba68b86be3..694d2c7c9f 100644 --- a/platform/e2e-tests/tests/api/mcp-gateway-auth-at-call-time.spec.ts +++ b/platform/e2e-tests/tests/api/mcp-gateway-auth-at-call-time.spec.ts @@ -44,7 +44,8 @@ test.describe("MCP Gateway - Auth at Call Time", () => { }) => { // 1. Create remote catalog item pointing to WireMock (static stubs pre-loaded) const catalogResponse = await createMcpCatalogItem(request, { - name: CATALOG_NAME, + slug: CATALOG_NAME, + displayName: CATALOG_NAME, description: "Test server for auth-at-call-time e2e test", serverType: "remote", serverUrl: `${WIREMOCK_INTERNAL_URL}${WIREMOCK_MCP_PATH}`, diff --git a/platform/e2e-tests/tests/api/mcp-gateway-jwt-propagation.ee.spec.ts b/platform/e2e-tests/tests/api/mcp-gateway-jwt-propagation.ee.spec.ts index 7de7db75dc..53215413ae 100644 --- a/platform/e2e-tests/tests/api/mcp-gateway-jwt-propagation.ee.spec.ts +++ b/platform/e2e-tests/tests/api/mcp-gateway-jwt-propagation.ee.spec.ts @@ -77,7 +77,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { let profileId: string | undefined; let catalogId: string | undefined; let serverId: string | undefined; - const catalogName = `jwks-propagation-test-${Date.now()}`; + const catalogSlug = `jwks-propagation-test-${Date.now()}`; try { // STEP 4: Create an MCP Gateway profile linked to the IdP @@ -104,7 +104,8 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { // STEP 5: Register the upstream MCP server as a remote MCP catalog item const catalogResponse = await createMcpCatalogItem(request, { - name: catalogName, + slug: catalogSlug, + displayName: catalogSlug, description: "E2E test: JWKS MCP server for JWT propagation testing", serverType: "remote", serverUrl: `${MCP_SERVER_JWKS_BACKEND_URL}/mcp`, @@ -117,7 +118,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { // the upstream server during tool discovery (it requires JWT auth). // Pass agentIds so discovered tools are automatically assigned to the profile. const installResponse = await installMcpServer(request, { - name: catalogName, + name: catalogSlug, catalogId, accessToken: jwt, agentIds: [pid], @@ -126,8 +127,8 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { serverId = mcpServer.id; // STEP 7: Verify tools from the upstream server were discovered and assigned - // The tool name format is: __ - const getServerInfoToolName = `${catalogName}${MCP_SERVER_TOOL_NAME_SEPARATOR}get-server-info`; + // The tool name format is: __ + const getServerInfoToolName = `${catalogSlug}${MCP_SERVER_TOOL_NAME_SEPARATOR}get-server-info`; const agentTool = await waitForAgentTool( request, pid, @@ -246,7 +247,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { let profileId: string | undefined; let catalogId: string | undefined; let serverId: string | undefined; - const catalogName = `jwks-reject-test-${Date.now()}`; + const catalogSlug = `jwks-reject-test-${Date.now()}`; try { // Create MCP Gateway WITHOUT IdP (so archestra token is used, not JWT) @@ -268,7 +269,8 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { // Register upstream server const catalogResponse = await createMcpCatalogItem(request, { - name: catalogName, + slug: catalogSlug, + displayName: catalogSlug, description: "E2E test: JWT rejection test", serverType: "remote", serverUrl: `${MCP_SERVER_JWKS_BACKEND_URL}/mcp`, @@ -280,7 +282,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { // tool discovery (the upstream server requires JWT auth). // Pass agentIds so discovered tools are automatically assigned to the profile. const installResponse = await installMcpServer(request, { - name: catalogName, + name: catalogSlug, catalogId, accessToken: jwt, agentIds: [pid], @@ -289,7 +291,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { serverId = mcpServer.id; // Wait for tools to be assigned - const toolName = `${catalogName}${MCP_SERVER_TOOL_NAME_SEPARATOR}get-server-info`; + const toolName = `${catalogSlug}${MCP_SERVER_TOOL_NAME_SEPARATOR}get-server-info`; await waitForAgentTool(request, pid, toolName, { maxAttempts: 30, delayMs: 2000, @@ -378,7 +380,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { let profileId: string | undefined; let catalogId: string | undefined; let serverId: string | undefined; - const catalogName = `jwks-local-k8s-test-${Date.now()}`; + const catalogSlug = `jwks-local-k8s-test-${Date.now()}`; try { // STEP 3: Create an MCP Gateway profile linked to the IdP @@ -406,7 +408,8 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { // Uses the same Docker image as the Helm-deployed instance but runs // as a K8s-orchestrated server via streamable-http transport. const catalogResponse = await createMcpCatalogItem(request, { - name: catalogName, + slug: catalogSlug, + displayName: catalogSlug, description: "E2E test: Local K8s JWKS MCP server for JWT propagation testing", serverType: "local", @@ -458,7 +461,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { // (the JWKS server requires JWT auth for all requests including MCP protocol). // Pass agentIds so discovered tools are automatically assigned to the profile. const installResponse = await installMcpServer(request, { - name: catalogName, + name: catalogSlug, catalogId, accessToken: jwt, agentIds: [pid], @@ -471,7 +474,7 @@ test.describe("MCP Gateway - JWT Propagation to Upstream MCP Server", () => { await waitForServerInstallation(request, sid); // STEP 7: Verify tools from the local server were discovered and assigned - const getServerInfoToolName = `${catalogName}${MCP_SERVER_TOOL_NAME_SEPARATOR}get-server-info`; + const getServerInfoToolName = `${catalogSlug}${MCP_SERVER_TOOL_NAME_SEPARATOR}get-server-info`; const agentTool = await waitForAgentTool( request, pid, diff --git a/platform/e2e-tests/tests/api/mcp-gateway.spec.ts b/platform/e2e-tests/tests/api/mcp-gateway.spec.ts index 4696943919..ebd5844ff5 100644 --- a/platform/e2e-tests/tests/api/mcp-gateway.spec.ts +++ b/platform/e2e-tests/tests/api/mcp-gateway.spec.ts @@ -480,7 +480,7 @@ test.describe("MCP Gateway - External MCP Server Tests", () => { if (!testServer) { // Install the server with team assignment const installResponse = await installMcpServer(request, { - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, teamId: defaultTeam.id, environmentValues: { diff --git a/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts b/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts index ecb28ce7f5..8463b634ca 100644 --- a/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts +++ b/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts @@ -237,7 +237,7 @@ test.describe("OAuth for Self-Hosted MCP Servers", () => { method: "post", urlSuffix: "/api/mcp_server", data: { - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, secretId, }, @@ -321,7 +321,7 @@ test.describe("OAuth for Self-Hosted MCP Servers", () => { method: "post", urlSuffix: "/api/mcp_server", data: { - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, secretId, environmentValues: { CUSTOM_ENV: "test-value" }, @@ -391,7 +391,7 @@ test.describe("OAuth for Self-Hosted MCP Servers", () => { method: "post", urlSuffix: "/api/mcp_server", data: { - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, secretId, environmentValues: { ADDITIONAL_VAR: "some-config" }, @@ -417,7 +417,8 @@ test.describe("OAuth for Self-Hosted MCP Servers", () => { }) => { // Create a catalog item without OAuth const createResponse = await createMcpCatalogItem(request, { - name: `no-oauth-test-${Date.now()}`, + slug: `no-oauth-test-${Date.now()}`, + displayName: `no-oauth-test-${Date.now()}`, description: "E2E test: server without OAuth", serverType: "remote", serverUrl: "https://example.com/mcp", diff --git a/platform/e2e-tests/tests/api/orchestrator.spec.ts b/platform/e2e-tests/tests/api/orchestrator.spec.ts index b4d739c127..5cb3fac4b8 100644 --- a/platform/e2e-tests/tests/api/orchestrator.spec.ts +++ b/platform/e2e-tests/tests/api/orchestrator.spec.ts @@ -83,7 +83,8 @@ test.describe("Orchestrator - MCP Server Installation and Execution", () => { // Use WIREMOCK_INTERNAL_URL because the backend needs to connect to WireMock // (In CI, backend runs in a K8s pod and needs the service DNS name) const catalogResponse = await createMcpCatalogItem(request, { - name: "Context7 - Remote", + slug: "Context7 - Remote", + displayName: "Context7 - Remote", description: "Context7 MCP Server for testing remote installation", serverType: "remote", serverUrl: `${WIREMOCK_INTERNAL_URL}/mcp/context7`, @@ -193,7 +194,7 @@ test.describe("Orchestrator - MCP Server Installation and Execution", () => { if (!testServer) { // Install the MCP server with team assignment const installResponse = await installMcpServer(request, { - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, teamId: defaultTeam.id, environmentValues: { @@ -267,7 +268,8 @@ test.describe("Orchestrator - MCP Server Installation and Execution", () => { // Create a catalog item for context7 MCP server using Docker image const catalogResponse = await createMcpCatalogItem(request, { - name: "Context7 - Docker Based", + slug: "Context7 - Docker Based", + displayName: "Context7 - Docker Based", description: "Context7 MCP Server for testing Docker image installation", serverType: "local", diff --git a/platform/e2e-tests/tests/api/ssrf-protection.spec.ts b/platform/e2e-tests/tests/api/ssrf-protection.spec.ts index 55ecb4d17f..ebfed9dc6b 100644 --- a/platform/e2e-tests/tests/api/ssrf-protection.spec.ts +++ b/platform/e2e-tests/tests/api/ssrf-protection.spec.ts @@ -110,7 +110,8 @@ test.describe("SSRF Protection - NetworkPolicy for MCP Servers", () => { // Create a catalog item for the SSRF test MCP server const catalogResponse = await createMcpCatalogItem(request, { - name: serverName, + slug: serverName, + displayName: serverName, description: "MCP server for SSRF protection testing - has a tool that attempts outbound HTTP requests", serverType: "local", diff --git a/platform/e2e-tests/utils.ts b/platform/e2e-tests/utils.ts index f003f3f768..4d94b3d335 100644 --- a/platform/e2e-tests/utils.ts +++ b/platform/e2e-tests/utils.ts @@ -123,15 +123,15 @@ export async function addCustomSelfHostedCatalogItem({ } const newCatalogItem = catalogItems.data.find( - (item) => item.name === catalogItemName, + (item) => item.slug === catalogItemName, ); if (!newCatalogItem) { - const itemNames = catalogItems.data.map((i) => i.name).join(", "); + const itemNames = catalogItems.data.map((i) => i.slug).join(", "); throw new Error( `Failed to find catalog item "${catalogItemName}". Available items: [${itemNames}]`, ); } - return { id: newCatalogItem.id, name: newCatalogItem.name }; + return { id: newCatalogItem.id, name: newCatalogItem.slug }; } export async function closeOpenDialogs( diff --git a/platform/frontend/src/app/llm/(costs)/limits/page.tsx b/platform/frontend/src/app/llm/(costs)/limits/page.tsx index 0812ea5170..168b444bc8 100644 --- a/platform/frontend/src/app/llm/(costs)/limits/page.tsx +++ b/platform/frontend/src/app/llm/(costs)/limits/page.tsx @@ -114,7 +114,7 @@ function LimitInlineForm({ onSave, onCancel, teams, - mcpServers, + catalogItems, tokenPrices, hasOrganizationMcpLimit, getTeamsWithMcpLimits, @@ -125,7 +125,7 @@ function LimitInlineForm({ onSave: (data: archestraApiTypes.CreateLimitData["body"]) => void; onCancel: () => void; teams: TeamData[]; - mcpServers: CatalogItem[]; + catalogItems: CatalogItem[]; tokenPrices: TokenPriceData[]; hasOrganizationMcpLimit?: (mcpServerName?: string) => boolean; getTeamsWithMcpLimits?: (mcpServerName?: string) => string[]; @@ -257,31 +257,31 @@ function LimitInlineForm({ - {mcpServers.length === 0 ? ( + {catalogItems.length === 0 ? (
No MCP servers available
) : ( - mcpServers.map((server) => { + catalogItems.map((server) => { // For MCP limits, check if this server already has a limit for the selected entity const isDisabled = limitType === "mcp_server_calls" && ((formData.entityType === "organization" && - hasOrganizationMcpLimit?.(server.name)) || + hasOrganizationMcpLimit?.(server.slug)) || (formData.entityType === "team" && formData.entityId && formData.entityId.trim() !== "" && - getTeamsWithMcpLimits?.(server.name)?.includes( + getTeamsWithMcpLimits?.(server.slug)?.includes( formData.entityId, ))); return ( - {server.name} + {server.displayName} ); }) @@ -438,7 +438,7 @@ function LimitRow({ onCancel, onDelete, teams, - mcpServers, + catalogItems, tokenPrices, getEntityName, getUsageStatus, @@ -451,7 +451,7 @@ function LimitRow({ onCancel: () => void; onDelete: () => void; teams: TeamData[]; - mcpServers: CatalogItem[]; + catalogItems: CatalogItem[]; tokenPrices: TokenPriceData[]; getEntityName: (limit: LimitData) => string; getUsageStatus: ( @@ -481,7 +481,7 @@ function LimitRow({ onSave={onSave} onCancel={onCancel} teams={teams} - mcpServers={mcpServers} + catalogItems={catalogItems} tokenPrices={tokenPrices} organizationId={organizationId} /> @@ -611,7 +611,7 @@ export default function LimitsPage() { // Data fetching hooks const { data: limits = [], isLoading: limitsLoading } = useLimits(); - const { data: mcpServers = [] } = useInternalMcpCatalog(); + const { data: catalogItems = [] } = useInternalMcpCatalog(); const { data: teams = [] } = useTeams(); const { data: organizationDetails } = useOrganization(); const { data: modelsWithApiKeys = [] } = useModelsWithApiKeys(); @@ -762,7 +762,7 @@ export default function LimitsPage() { onSave={handleCreateLimit} onCancel={handleCancelEdit} teams={teams} - mcpServers={mcpServers} + catalogItems={catalogItems} tokenPrices={tokenPrices} organizationId={organizationDetails?.id || ""} /> @@ -791,7 +791,7 @@ export default function LimitsPage() { onCancel={handleCancelEdit} onDelete={() => handleDeleteLimit(limit.id)} teams={teams} - mcpServers={mcpServers} + catalogItems={catalogItems} tokenPrices={tokenPrices} getEntityName={getEntityName} getUsageStatus={getUsageStatus} diff --git a/platform/frontend/src/app/mcp/logs/page.client.tsx b/platform/frontend/src/app/mcp/logs/page.client.tsx index 718b2b54e0..35f6ed92d4 100644 --- a/platform/frontend/src/app/mcp/logs/page.client.tsx +++ b/platform/frontend/src/app/mcp/logs/page.client.tsx @@ -170,8 +170,8 @@ function McpToolCallsTable({ const map = new Map(); if (mcpServers) { for (const server of mcpServers) { - if (server.catalogName) { - map.set(server.name, server.catalogName); + if (server.catalogSlug) { + map.set(server.name, server.catalogSlug); } } } diff --git a/platform/frontend/src/app/mcp/registry/_parts/InternalMCPCatalog.tsx b/platform/frontend/src/app/mcp/registry/_parts/InternalMCPCatalog.tsx index 630d7b3274..a2643ae4ad 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/InternalMCPCatalog.tsx +++ b/platform/frontend/src/app/mcp/registry/_parts/InternalMCPCatalog.tsx @@ -427,7 +427,7 @@ export function InternalMCPCatalog({ const handleInstallPlaywright = async (catalogItem: CatalogItem) => { setInstallingItemId(catalogItem.id); const result = await installMutation.mutateAsync({ - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, dontShowToast: true, }); @@ -471,7 +471,7 @@ export function InternalMCPCatalog({ ) => { setInstallingItemId(catalogItem.id); const result = await installMutation.mutateAsync({ - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, ...(teamId && { teamId }), dontShowToast: true, @@ -530,7 +530,7 @@ export function InternalMCPCatalog({ setInstallingItemId(catalogItem.id); await installMutation.mutateAsync({ - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, teamId: result.teamId ?? undefined, }); @@ -585,7 +585,8 @@ export function InternalMCPCatalog({ if (reauthServerId) { await reauthMutation.mutateAsync({ id: reauthServerId, - name: localServerCatalogItem.name, + slug: localServerCatalogItem.slug, + displayName: localServerCatalogItem.displayName, environmentValues: installResult.environmentValues, isByosVault: installResult.isByosVault, }); @@ -610,7 +611,8 @@ export function InternalMCPCatalog({ try { await reinstallMutation.mutateAsync({ id: serverIdToReinstall, - name: localServerCatalogItem.name, + slug: localServerCatalogItem.slug, + displayName: localServerCatalogItem.displayName, environmentValues: installResult.environmentValues, isByosVault: installResult.isByosVault, serviceAccount: installResult.serviceAccount, @@ -635,7 +637,7 @@ export function InternalMCPCatalog({ setInstallingItemId(localServerCatalogItem.id); const result = await installMutation.mutateAsync({ - name: localServerCatalogItem.name, + name: localServerCatalogItem.slug, catalogId: localServerCatalogItem.id, environmentValues: installResult.environmentValues, isByosVault: installResult.isByosVault, @@ -678,7 +680,8 @@ export function InternalMCPCatalog({ if (reauthServerId) { await reauthMutation.mutateAsync({ id: reauthServerId, - name: catalogItem.name, + slug: catalogItem.slug, + displayName: catalogItem.displayName, ...(accessToken && { accessToken }), ...(result.isByosVault && { userConfigValues: result.metadata as Record, @@ -700,7 +703,7 @@ export function InternalMCPCatalog({ setInstallingItemId(catalogItem.id); await installMutation.mutateAsync({ - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, ...(accessToken && { accessToken }), ...(result.isByosVault && { @@ -852,7 +855,8 @@ export function InternalMCPCatalog({ try { await reinstallMutation.mutateAsync({ id: installedServer.id, - name: catalogItem.name, + slug: catalogItem.slug, + displayName: catalogItem.displayName, }); } finally { // Clear installing state whether success or error @@ -895,7 +899,8 @@ export function InternalMCPCatalog({ try { await reinstallMutation.mutateAsync({ id: installedServer.id, - name: catalogItemForReinstall.name, + slug: catalogItemForReinstall.slug, + displayName: catalogItemForReinstall.displayName, }); } finally { // Clear installing state whether success or error @@ -958,11 +963,9 @@ export function InternalMCPCatalog({ if (!normalizedQuery) return items; return items.filter((item) => { - const labelText = - typeof item.name === "string" ? item.name.toLowerCase() : ""; return ( - item.name.toLowerCase().includes(normalizedQuery) || - labelText.includes(normalizedQuery) + item.slug.toLowerCase().includes(normalizedQuery) || + item.displayName.toLowerCase().includes(normalizedQuery) ); }); }; @@ -1053,7 +1056,7 @@ export function InternalMCPCatalog({ onReinstall={() => handleReinstall(item)} onEdit={() => setEditingItem(item)} onDetails={() => { - setDetailsServerName(item.name); + setDetailsServerName(item.slug); }} onDelete={() => setDeletingItem(item)} onCancelInstallation={handleCancelInstallation} @@ -1110,7 +1113,7 @@ export function InternalMCPCatalog({ onReinstall={() => handleReinstall(item)} onEdit={() => setEditingItem(item)} onDetails={() => { - setDetailsServerName(item.name); + setDetailsServerName(item.slug); }} onDelete={() => setDeletingItem(item)} onCancelInstallation={handleCancelInstallation} @@ -1223,7 +1226,7 @@ export function InternalMCPCatalog({ closeDialog("oauth"); } }} - serverName={selectedCatalogItem?.name || ""} + serverName={selectedCatalogItem?.displayName || ""} onConfirm={handleOAuthConfirm} onCancel={() => { closeDialog("oauth"); @@ -1245,7 +1248,7 @@ export function InternalMCPCatalog({ }} isRemoteServer={catalogItemForReinstall?.serverType === "remote"} onConfirm={handleReinstallConfirm} - serverName={catalogItemForReinstall?.name || ""} + serverName={catalogItemForReinstall?.displayName || ""} isReinstalling={reinstallMutation.isPending} /> diff --git a/platform/frontend/src/app/mcp/registry/_parts/archestra-catalog-tab.tsx b/platform/frontend/src/app/mcp/registry/_parts/archestra-catalog-tab.tsx index dac105fe83..508ff7a74c 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/archestra-catalog-tab.tsx +++ b/platform/frontend/src/app/mcp/registry/_parts/archestra-catalog-tab.tsx @@ -114,7 +114,7 @@ export function ArchestraCatalogTab({ // Create a Set of catalog item names for efficient lookup const catalogServerNames = useMemo( - () => new Set(catalogItems?.map((item) => item.name) || []), + () => new Set(catalogItems?.map((item) => item.slug) || []), [catalogItems], ); diff --git a/platform/frontend/src/app/mcp/registry/_parts/delete-catalog-dialog.tsx b/platform/frontend/src/app/mcp/registry/_parts/delete-catalog-dialog.tsx index c96ac4013c..c2d5d68b4f 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/delete-catalog-dialog.tsx +++ b/platform/frontend/src/app/mcp/registry/_parts/delete-catalog-dialog.tsx @@ -47,7 +47,7 @@ export function DeleteCatalogDialog({ (() => { return installationCount > 0 ? (
- +
There are currently {installationCount}{" "} installation(s) of this server. Deleting this catalog @@ -55,7 +55,7 @@ export function DeleteCatalogDialog({
) : ( - + ); })()} diff --git a/platform/frontend/src/app/mcp/registry/_parts/local-server-install-dialog.tsx b/platform/frontend/src/app/mcp/registry/_parts/local-server-install-dialog.tsx index 61a8b6a893..5a55e83da9 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/local-server-install-dialog.tsx +++ b/platform/frontend/src/app/mcp/registry/_parts/local-server-install-dialog.tsx @@ -321,7 +321,7 @@ export function LocalServerInstallDialog({ : isReinstall ? "Reinstall" : "Install"}{" "} - - {catalogItem?.name} + - {catalogItem?.displayName} {catalogItem?.instructions && ( diff --git a/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts b/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts index 085653d42e..dc4bb155a6 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts +++ b/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts @@ -16,7 +16,8 @@ export function transformFormToApiData( values: McpCatalogFormValues, ): McpCatalogApiData { const data: McpCatalogApiData = { - name: values.name, + slug: values.name, + displayName: values.name, description: values.description || null, serverType: values.serverType, icon: values.icon ?? null, @@ -87,7 +88,7 @@ export function transformFormToApiData( : values.serverUrl || ""; data.oauthConfig = { - name: values.name, // Use name as OAuth provider name + name: values.name, // Use display name as OAuth provider name server_url: oauthServerUrl, // OAuth server URL for discovery/authorization client_id: values.oauthConfig.client_id || "", // Only include client_secret if no BYOS vault path is set @@ -177,8 +178,8 @@ export function transformCatalogItemToFormValues( authMethod = "bearer"; } else if ( // Special case: GitHub server uses Bearer Token but external catalog doesn't define userConfig - item.name.includes("githubcopilot") || - item.name.includes("github") + item.slug.includes("githubcopilot") || + item.slug.includes("github") ) { authMethod = "bearer"; } @@ -306,7 +307,7 @@ export function transformCatalogItemToFormValues( } return { - name: item.name, + name: item.displayName, description: item.description || "", icon: item.icon ?? null, serverType: item.serverType as "remote" | "local", diff --git a/platform/frontend/src/app/mcp/registry/_parts/mcp-server-card.tsx b/platform/frontend/src/app/mcp/registry/_parts/mcp-server-card.tsx index d7106db103..c26cdb331e 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/mcp-server-card.tsx +++ b/platform/frontend/src/app/mcp/registry/_parts/mcp-server-card.tsx @@ -247,7 +247,7 @@ export function McpServerCard({ const handleChatWithMcpServer = async () => { setIsChatCreating(true); - const agentName = item.label || item.name; + const agentName = item.label || item.displayName; try { // Get or create: check if a personal agent with this name already exists for the current user const { data: existingAgents } = await archestraApiSdk.getAllAgents({ @@ -652,7 +652,7 @@ export function McpServerCard({ size="sm" variant="outline" className="w-full" - data-testid={`${E2eTestId.ConnectCatalogItemButton}-${item.name}`} + data-testid={`${E2eTestId.ConnectCatalogItemButton}-${item.slug}`} > Install @@ -716,7 +716,7 @@ export function McpServerCard({ size="sm" variant="outline" className="w-full" - data-testid={`${E2eTestId.ConnectCatalogItemButton}-${item.name}`} + data-testid={`${E2eTestId.ConnectCatalogItemButton}-${item.slug}`} > Install @@ -790,16 +790,16 @@ export function McpServerCard({ return (
- + - {item.name} + {item.displayName}
@@ -842,14 +842,14 @@ export function McpServerCard({
Failed to start MCP server,{" "} {" "} @@ -858,7 +858,7 @@ export function McpServerCard({ type="button" onClick={() => openSettingsPage("configuration")} className="text-primary hover:underline cursor-pointer" - data-testid={`${E2eTestId.McpLogsEditConfigButton}-${item.name}`} + data-testid={`${E2eTestId.McpLogsEditConfigButton}-${item.slug}`} > edit your config diff --git a/platform/frontend/src/app/mcp/registry/_parts/mcp-server-settings-dialog.tsx b/platform/frontend/src/app/mcp/registry/_parts/mcp-server-settings-dialog.tsx index 9a4f9b2aaa..b0078f41d2 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/mcp-server-settings-dialog.tsx +++ b/platform/frontend/src/app/mcp/registry/_parts/mcp-server-settings-dialog.tsx @@ -259,7 +259,7 @@ export function McpServerSettingsDialog({ showCloseButton={false} > - {item.label || item.name} Settings + {item.label || item.displayName} Settings Server settings and configuration @@ -271,9 +271,9 @@ export function McpServerSettingsDialog({
- +
- {item.label || item.name} + {item.label || item.displayName}
{summary && ( @@ -396,7 +396,7 @@ export function McpServerSettingsDialog({ - Install {catalogItem.name} + Install {catalogItem.displayName} This MCP server doesn't require authentication. Click Install to diff --git a/platform/frontend/src/app/mcp/registry/_parts/remote-server-install-dialog.tsx b/platform/frontend/src/app/mcp/registry/_parts/remote-server-install-dialog.tsx index 18674ae58b..70bbcb5fe6 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/remote-server-install-dialog.tsx +++ b/platform/frontend/src/app/mcp/registry/_parts/remote-server-install-dialog.tsx @@ -251,7 +251,7 @@ export function RemoteServerInstallDialog({ {isReauth ? "Re-authenticate" : "Install Server"} - {catalogItem.name} + {catalogItem.displayName}
diff --git a/platform/frontend/src/app/mcp/tool-policies/_parts/assigned-tools-table.tsx b/platform/frontend/src/app/mcp/tool-policies/_parts/assigned-tools-table.tsx index 61c5c91581..f07fde514c 100644 --- a/platform/frontend/src/app/mcp/tool-policies/_parts/assigned-tools-table.tsx +++ b/platform/frontend/src/app/mcp/tool-policies/_parts/assigned-tools-table.tsx @@ -501,11 +501,13 @@ export function AssignedToolsTable({ variant="default" className="bg-indigo-500 max-w-[150px]" > - {catalogItem.name} + + {catalogItem.displayName} + -

{catalogItem.name}

+

{catalogItem.displayName}

@@ -739,7 +741,7 @@ export function AssignedToolsTable({ const uniqueOrigins = useMemo(() => { const origins = new Set<{ id: string; name: string }>(); internalMcpCatalogItems?.forEach((item) => { - origins.add({ id: item.id, name: item.name }); + origins.add({ id: item.id, name: item.displayName }); }); return Array.from(origins); }, [internalMcpCatalogItems]); diff --git a/platform/frontend/src/app/mcp/tool-policies/_parts/tool-details-dialog.tsx b/platform/frontend/src/app/mcp/tool-policies/_parts/tool-details-dialog.tsx index b44621ccb0..ae16190b7f 100644 --- a/platform/frontend/src/app/mcp/tool-policies/_parts/tool-details-dialog.tsx +++ b/platform/frontend/src/app/mcp/tool-policies/_parts/tool-details-dialog.tsx @@ -148,7 +148,7 @@ export function ToolDetailsDialog({ -

{catalogItem?.name || "MCP Server"}

+

{catalogItem?.displayName || "MCP Server"}

diff --git a/platform/frontend/src/app/oauth-callback/page.tsx b/platform/frontend/src/app/oauth-callback/page.tsx index 605873cbbb..709116b631 100644 --- a/platform/frontend/src/app/oauth-callback/page.tsx +++ b/platform/frontend/src/app/oauth-callback/page.tsx @@ -79,7 +79,8 @@ function OAuthCallbackContent() { await reauthMutation.mutateAsync({ id: mcpServerId, secretId, - name, + slug: name, + displayName: name, }); clearCallbackProcessing(code, state); diff --git a/platform/frontend/src/components/agent-tools-editor.tsx b/platform/frontend/src/components/agent-tools-editor.tsx index 25b43051f8..52db53dbc3 100644 --- a/platform/frontend/src/components/agent-tools-editor.tsx +++ b/platform/frontend/src/components/agent-tools-editor.tsx @@ -174,7 +174,7 @@ const AgentToolsEditorContent = forwardRef< if (aCount === 0 && bCount > 0) return 1; // Finally, sort alphabetically by name - return a.name.localeCompare(b.name); + return a.displayName.localeCompare(b.displayName); }); }, [catalogItems, assignedToolsByCatalog, toolCountByCatalog]); @@ -203,7 +203,7 @@ const AgentToolsEditorContent = forwardRef< (q) => (q?.data as CatalogTool[] | undefined) ?? undefined, ); const result = getDefaultArchestraToolIds( - catalogItems, + catalogItems.map((c) => ({ id: c.id, name: c.displayName })), toolsByCatalogIndex, ); if (!result) return; @@ -441,7 +441,7 @@ const AgentToolsEditorContent = forwardRef< const isDisabled = hasNoTools || hasNoCredentials; return { id: catalog.id, - name: catalog.name, + name: catalog.displayName, description: catalog.description || undefined, icon: ( - {catalog.name} + {catalog.displayName} {isDisabled @@ -772,7 +772,7 @@ function McpServerPill({ catalogId={catalogItem.id} size={14} /> - {catalogItem.name} + {catalogItem.displayName} ({displayedCount}) @@ -786,7 +786,7 @@ function McpServerPill({ e.stopPropagation(); onRemove(catalogItem.id); }} - aria-label={`Remove ${catalogItem.name}`} + aria-label={`Remove ${catalogItem.displayName}`} > @@ -802,7 +802,7 @@ function McpServerPill({ >
-

{catalogItem.name}

+

{catalogItem.displayName}

{catalogItem.description && (

{catalogItem.description} diff --git a/platform/frontend/src/components/chat/initial-agent-selector.tsx b/platform/frontend/src/components/chat/initial-agent-selector.tsx index 543631d384..f0aeb70bc7 100644 --- a/platform/frontend/src/components/chat/initial-agent-selector.tsx +++ b/platform/frontend/src/components/chat/initial-agent-selector.tsx @@ -630,7 +630,7 @@ function AssignedToolsGrid({ e.stopPropagation(); handleRemove(catalog.id); }} - title={`Remove ${catalog.name}`} + title={`Remove ${catalog.displayName}`} > @@ -645,7 +645,7 @@ function AssignedToolsGrid({ size={24} /> - {catalog.name} + {catalog.displayName} {info?.count ?? 0} {(info?.count ?? 0) === 1 ? "tool" : "tools"} @@ -722,7 +722,7 @@ function AddToolView({ const lower = search.toLowerCase(); items = items.filter( (c) => - c.name.toLowerCase().includes(lower) || + c.displayName.toLowerCase().includes(lower) || c.description?.toLowerCase().includes(lower), ); } @@ -817,7 +817,7 @@ function AddToolView({ size={28} /> - {catalog.name} + {catalog.displayName} {catalog.description && (

@@ -870,7 +870,7 @@ function AddToolView({ onOpenChange={(open) => { if (!open) installer.closeOAuth(); }} - serverName={installer.selectedCatalogItem?.name || ""} + serverName={installer.selectedCatalogItem?.displayName || ""} onConfirm={installer.handleOAuthConfirm} onCancel={installer.closeOAuth} catalogId={installer.selectedCatalogItem?.id} @@ -1025,7 +1025,7 @@ function ConfigureToolView({ return (

- +
{showCredentialSelector && ( @@ -1437,7 +1437,7 @@ function ToolServerAvatarGroup({ ...catalogs.map((c) => ({ key: c.id, icon: , - tooltip: c.name, + tooltip: c.displayName, })), ]; diff --git a/platform/frontend/src/components/chat/mcp-install-dialogs.tsx b/platform/frontend/src/components/chat/mcp-install-dialogs.tsx index 9bcc0f1405..bd42e13a65 100644 --- a/platform/frontend/src/components/chat/mcp-install-dialogs.tsx +++ b/platform/frontend/src/components/chat/mcp-install-dialogs.tsx @@ -26,7 +26,7 @@ export function McpInstallDialogs({ orchestrator }: McpInstallDialogsProps) { onOpenChange={(open) => { if (!open) orchestrator.closeOAuth(); }} - serverName={orchestrator.selectedCatalogItem?.name || ""} + serverName={orchestrator.selectedCatalogItem?.displayName || ""} onConfirm={orchestrator.handleOAuthConfirm} onCancel={orchestrator.closeOAuth} catalogId={orchestrator.selectedCatalogItem?.id} diff --git a/platform/frontend/src/components/chat/tool-error-logs-button.tsx b/platform/frontend/src/components/chat/tool-error-logs-button.tsx index 7d6570b872..fb4ccff6f6 100644 --- a/platform/frontend/src/components/chat/tool-error-logs-button.tsx +++ b/platform/frontend/src/components/chat/tool-error-logs-button.tsx @@ -32,9 +32,9 @@ export function ToolErrorLogsButton({ toolName }: ToolErrorLogsButtonProps) { // Find servers where the catalog name matches the tool's server name prefix return allMcpServers .filter((server) => { - // Match by catalogName (which is the server name used in tool naming) + // Match by catalogSlug (which is the server name used in tool naming) return ( - server.catalogName === mcpServerName && server.serverType === "local" + server.catalogSlug === mcpServerName && server.serverType === "local" ); }) .map((server) => ({ diff --git a/platform/frontend/src/components/mcp-connection-instructions.tsx b/platform/frontend/src/components/mcp-connection-instructions.tsx index 08c3411d41..1d7c4a3773 100644 --- a/platform/frontend/src/components/mcp-connection-instructions.tsx +++ b/platform/frontend/src/components/mcp-connection-instructions.tsx @@ -738,7 +738,7 @@ interface ReadOnlyMcpServerPillProps { credentialSourceMcpServerId?: string | null; catalogItems: Array<{ id: string; - name: string; + displayName: string; description?: string | null; }>; useDynamicTeamCredential?: boolean; @@ -759,7 +759,7 @@ function ReadOnlyMcpServerPill({ : null; // Use catalog name if available, otherwise fall back to server name - const displayName = catalogItem?.name ?? server.name; + const displayName = catalogItem?.displayName ?? server.name; const displayDescription = catalogItem?.description ?? server.description ?? null; diff --git a/platform/frontend/src/lib/mcp-install-orchestrator.hook.ts b/platform/frontend/src/lib/mcp-install-orchestrator.hook.ts index 9c9a9da557..39fddb18b4 100644 --- a/platform/frontend/src/lib/mcp-install-orchestrator.hook.ts +++ b/platform/frontend/src/lib/mcp-install-orchestrator.hook.ts @@ -193,7 +193,8 @@ export function useMcpInstallOrchestrator() { await reauthMutation.mutateAsync({ id: reauthServerId, - name: catalogItem.name, + slug: catalogItem.slug, + displayName: catalogItem.displayName, ...(accessToken && { accessToken }), ...(result.isByosVault && { userConfigValues: result.metadata as Record, @@ -220,7 +221,7 @@ export function useMcpInstallOrchestrator() { : undefined; await installMutation.mutateAsync({ - name: catalogItem.name, + name: catalogItem.slug, catalogId: catalogItem.id, ...(accessToken && { accessToken }), ...(result.isByosVault && { @@ -240,7 +241,8 @@ export function useMcpInstallOrchestrator() { if (reauthServerId) { await reauthMutation.mutateAsync({ id: reauthServerId, - name: localServerCatalogItem.name, + slug: localServerCatalogItem.slug, + displayName: localServerCatalogItem.displayName, environmentValues: installResult.environmentValues, isByosVault: installResult.isByosVault, }); @@ -282,7 +284,7 @@ export function useMcpInstallOrchestrator() { } await installMutation.mutateAsync({ - name: localServerCatalogItem.name, + name: localServerCatalogItem.slug, catalogId: localServerCatalogItem.id, environmentValues: installResult.environmentValues, isByosVault: installResult.isByosVault, @@ -298,7 +300,7 @@ export function useMcpInstallOrchestrator() { if (!noAuthCatalogItem) return; await installMutation.mutateAsync({ - name: noAuthCatalogItem.name, + name: noAuthCatalogItem.slug, catalogId: noAuthCatalogItem.id, teamId: result.teamId ?? undefined, }); diff --git a/platform/frontend/src/lib/mcp-server.query.ts b/platform/frontend/src/lib/mcp-server.query.ts index ad7104d098..21d8ebd674 100644 --- a/platform/frontend/src/lib/mcp-server.query.ts +++ b/platform/frontend/src/lib/mcp-server.query.ts @@ -219,14 +219,15 @@ export function useReauthenticateMcpServer() { return useMutation({ mutationFn: async (data: { id: string; - name: string; + slug: string; + displayName: string; secretId?: string; accessToken?: string; userConfigValues?: Record; environmentValues?: Record; isByosVault?: boolean; }) => { - const { id, name, ...body } = data; + const { id, slug, displayName, ...body } = data; const response = await reauthenticateMcpServer({ path: { id }, body, @@ -240,10 +241,10 @@ export function useReauthenticateMcpServer() { onSuccess: async (_, variables) => { await queryClient.refetchQueries({ queryKey: ["mcp-servers"] }); invalidateToolAssignmentQueries(queryClient); - toast.success(`Successfully re-authenticated ${variables.name}`); + toast.success(`Successfully re-authenticated ${variables.displayName}`); }, onError: (_error, variables) => { - toast.error(`Failed to re-authenticate ${variables.name}`); + toast.error(`Failed to re-authenticate ${variables.displayName}`); }, }); } @@ -258,12 +259,13 @@ export function useReinstallMcpServer() { return useMutation({ mutationFn: async (data: { id: string; - name: string; + slug: string; + displayName: string; environmentValues?: Record; isByosVault?: boolean; serviceAccount?: string; }) => { - const { id, name, ...body } = data; + const { id, slug, displayName, ...body } = data; const response = await reinstallMcpServer({ path: { id }, body, @@ -272,7 +274,7 @@ export function useReinstallMcpServer() { handleApiError(response.error); return null; } - return { data: response.data, name }; + return { data: response.data, displayName }; }, onSuccess: async (_result, variables) => { // Refetch servers to get updated status (will show "pending" initially) diff --git a/platform/shared/access-control.ts b/platform/shared/access-control.ts index dc8b315b87..2a6d4a6208 100644 --- a/platform/shared/access-control.ts +++ b/platform/shared/access-control.ts @@ -470,7 +470,7 @@ export const requiredEndpointPermissionsMap: Partial< [RouteId.DeleteInternalMcpCatalogItem]: { mcpRegistry: ["delete"], }, - [RouteId.DeleteInternalMcpCatalogItemByName]: { + [RouteId.DeleteInternalMcpCatalogItemBySlug]: { mcpRegistry: ["delete"], }, [RouteId.GetInternalMcpCatalogLabelKeys]: { diff --git a/platform/shared/hey-api/clients/api/index.ts b/platform/shared/hey-api/clients/api/index.ts index ed7ea1aa4d..857c6e6e16 100644 --- a/platform/shared/hey-api/clients/api/index.ts +++ b/platform/shared/hey-api/clients/api/index.ts @@ -59,7 +59,7 @@ export { deleteIdentityProvider, deleteIncomingEmailSubscription, deleteInternalMcpCatalogItem, - deleteInternalMcpCatalogItemByName, + deleteInternalMcpCatalogItemBySlug, deleteKnowledgeBase, deleteLimit, deleteMcpServer, @@ -575,11 +575,11 @@ export type { DeleteIncomingEmailSubscriptionErrors, DeleteIncomingEmailSubscriptionResponse, DeleteIncomingEmailSubscriptionResponses, - DeleteInternalMcpCatalogItemByNameData, - DeleteInternalMcpCatalogItemByNameError, - DeleteInternalMcpCatalogItemByNameErrors, - DeleteInternalMcpCatalogItemByNameResponse, - DeleteInternalMcpCatalogItemByNameResponses, + DeleteInternalMcpCatalogItemBySlugData, + DeleteInternalMcpCatalogItemBySlugError, + DeleteInternalMcpCatalogItemBySlugErrors, + DeleteInternalMcpCatalogItemBySlugResponse, + DeleteInternalMcpCatalogItemBySlugResponses, DeleteInternalMcpCatalogItemData, DeleteInternalMcpCatalogItemError, DeleteInternalMcpCatalogItemErrors, diff --git a/platform/shared/hey-api/clients/api/sdk.gen.ts b/platform/shared/hey-api/clients/api/sdk.gen.ts index 6575d2fb8e..a4a527dfd6 100644 --- a/platform/shared/hey-api/clients/api/sdk.gen.ts +++ b/platform/shared/hey-api/clients/api/sdk.gen.ts @@ -2,7 +2,7 @@ import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; -import type { AddMcpServerInstallationRequestNoteData, AddMcpServerInstallationRequestNoteErrors, AddMcpServerInstallationRequestNoteResponses, AddTeamExternalGroupData, AddTeamExternalGroupErrors, AddTeamExternalGroupResponses, AddTeamMemberData, AddTeamMemberErrors, AddTeamMemberResponses, AnthropicMessagesWithAgentData, AnthropicMessagesWithAgentErrors, AnthropicMessagesWithAgentResponses, AnthropicMessagesWithDefaultAgentData, AnthropicMessagesWithDefaultAgentErrors, AnthropicMessagesWithDefaultAgentResponses, ApproveMcpServerInstallationRequestData, ApproveMcpServerInstallationRequestErrors, ApproveMcpServerInstallationRequestResponses, AssignConnectorToKnowledgeBasesData, AssignConnectorToKnowledgeBasesErrors, AssignConnectorToKnowledgeBasesResponses, AssignToolToAgentData, AssignToolToAgentErrors, AssignToolToAgentResponses, AutoConfigureAgentToolPoliciesData, AutoConfigureAgentToolPoliciesErrors, AutoConfigureAgentToolPoliciesResponses, BedrockConverseStreamWithAgentAndModelData, BedrockConverseStreamWithAgentAndModelResponses, BedrockConverseStreamWithAgentData, BedrockConverseStreamWithAgentResponses, BedrockConverseStreamWithDefaultAgentData, BedrockConverseStreamWithDefaultAgentResponses, BedrockConverseWithAgentAndModelData, BedrockConverseWithAgentAndModelErrors, BedrockConverseWithAgentAndModelResponses, BedrockConverseWithAgentData, BedrockConverseWithAgentErrors, BedrockConverseWithAgentResponses, BedrockConverseWithDefaultAgentData, BedrockConverseWithDefaultAgentErrors, BedrockConverseWithDefaultAgentResponses, BulkAssignToolsData, BulkAssignToolsErrors, BulkAssignToolsResponses, BulkUpdateChatOpsBindingsData, BulkUpdateChatOpsBindingsErrors, BulkUpdateChatOpsBindingsResponses, BulkUpsertDefaultCallPolicyData, BulkUpsertDefaultCallPolicyErrors, BulkUpsertDefaultCallPolicyResponses, BulkUpsertDefaultResultPolicyData, BulkUpsertDefaultResultPolicyErrors, BulkUpsertDefaultResultPolicyResponses, CerebrasChatCompletionsWithAgentData, CerebrasChatCompletionsWithAgentErrors, CerebrasChatCompletionsWithAgentResponses, CerebrasChatCompletionsWithDefaultAgentData, CerebrasChatCompletionsWithDefaultAgentErrors, CerebrasChatCompletionsWithDefaultAgentResponses, CheckInvitationData, CheckInvitationErrors, CheckInvitationResponses, CheckSecretsConnectivityData, CheckSecretsConnectivityErrors, CheckSecretsConnectivityResponses, CheckTeamVaultFolderConnectivityData, CheckTeamVaultFolderConnectivityErrors, CheckTeamVaultFolderConnectivityResponses, CohereChatWithAgentData, CohereChatWithAgentErrors, CohereChatWithAgentResponses, CohereChatWithDefaultAgentData, CohereChatWithDefaultAgentErrors, CohereChatWithDefaultAgentResponses, CompleteOnboardingData, CompleteOnboardingErrors, CompleteOnboardingResponses, CreateAgentData, CreateAgentErrors, CreateAgentResponses, CreateChatApiKeyData, CreateChatApiKeyErrors, CreateChatApiKeyResponses, CreateChatConversationData, CreateChatConversationErrors, CreateChatConversationResponses, CreateChatOpsDmBindingData, CreateChatOpsDmBindingErrors, CreateChatOpsDmBindingResponses, CreateConnectorData, CreateConnectorErrors, CreateConnectorResponses, CreateDualLlmConfigData, CreateDualLlmConfigErrors, CreateDualLlmConfigResponses, CreateIdentityProviderData, CreateIdentityProviderErrors, CreateIdentityProviderResponses, CreateInternalMcpCatalogItemData, CreateInternalMcpCatalogItemErrors, CreateInternalMcpCatalogItemResponses, CreateKnowledgeBaseData, CreateKnowledgeBaseErrors, CreateKnowledgeBaseResponses, CreateLimitData, CreateLimitErrors, CreateLimitResponses, CreateMcpServerInstallationRequestData, CreateMcpServerInstallationRequestErrors, CreateMcpServerInstallationRequestResponses, CreateOptimizationRuleData, CreateOptimizationRuleErrors, CreateOptimizationRuleResponses, CreateRoleData, CreateRoleErrors, CreateRoleResponses, CreateTeamData, CreateTeamErrors, CreateTeamResponses, CreateToolInvocationPolicyData, CreateToolInvocationPolicyErrors, CreateToolInvocationPolicyResponses, CreateTrustedDataPolicyData, CreateTrustedDataPolicyErrors, CreateTrustedDataPolicyResponses, CreateVirtualApiKeyData, CreateVirtualApiKeyErrors, CreateVirtualApiKeyResponses, DeclineMcpServerInstallationRequestData, DeclineMcpServerInstallationRequestErrors, DeclineMcpServerInstallationRequestResponses, DeepseekChatCompletionsWithAgentData, DeepseekChatCompletionsWithAgentErrors, DeepseekChatCompletionsWithAgentResponses, DeepseekChatCompletionsWithDefaultAgentData, DeepseekChatCompletionsWithDefaultAgentErrors, DeepseekChatCompletionsWithDefaultAgentResponses, DeleteAgentData, DeleteAgentDelegationData, DeleteAgentDelegationErrors, DeleteAgentDelegationResponses, DeleteAgentErrors, DeleteAgentResponses, DeleteChatApiKeyData, DeleteChatApiKeyErrors, DeleteChatApiKeyResponses, DeleteChatConversationData, DeleteChatConversationErrors, DeleteChatConversationResponses, DeleteChatOpsBindingData, DeleteChatOpsBindingErrors, DeleteChatOpsBindingResponses, DeleteConnectorData, DeleteConnectorErrors, DeleteConnectorResponses, DeleteConversationEnabledToolsData, DeleteConversationEnabledToolsErrors, DeleteConversationEnabledToolsResponses, DeleteDualLlmConfigData, DeleteDualLlmConfigErrors, DeleteDualLlmConfigResponses, DeleteIdentityProviderData, DeleteIdentityProviderErrors, DeleteIdentityProviderResponses, DeleteIncomingEmailSubscriptionData, DeleteIncomingEmailSubscriptionErrors, DeleteIncomingEmailSubscriptionResponses, DeleteInternalMcpCatalogItemByNameData, DeleteInternalMcpCatalogItemByNameErrors, DeleteInternalMcpCatalogItemByNameResponses, DeleteInternalMcpCatalogItemData, DeleteInternalMcpCatalogItemErrors, DeleteInternalMcpCatalogItemResponses, DeleteKnowledgeBaseData, DeleteKnowledgeBaseErrors, DeleteKnowledgeBaseResponses, DeleteLimitData, DeleteLimitErrors, DeleteLimitResponses, DeleteMcpServerData, DeleteMcpServerErrors, DeleteMcpServerInstallationRequestData, DeleteMcpServerInstallationRequestErrors, DeleteMcpServerInstallationRequestResponses, DeleteMcpServerResponses, DeleteOptimizationRuleData, DeleteOptimizationRuleErrors, DeleteOptimizationRuleResponses, DeletePendingSignupMemberData, DeletePendingSignupMemberErrors, DeletePendingSignupMemberResponses, DeleteRoleData, DeleteRoleErrors, DeleteRoleResponses, DeleteTeamData, DeleteTeamErrors, DeleteTeamResponses, DeleteTeamVaultFolderData, DeleteTeamVaultFolderErrors, DeleteTeamVaultFolderResponses, DeleteToolData, DeleteToolErrors, DeleteToolInvocationPolicyData, DeleteToolInvocationPolicyErrors, DeleteToolInvocationPolicyResponses, DeleteToolResponses, DeleteTrustedDataPolicyData, DeleteTrustedDataPolicyErrors, DeleteTrustedDataPolicyResponses, DeleteVirtualApiKeyData, DeleteVirtualApiKeyErrors, DeleteVirtualApiKeyResponses, ForkSharedConversationData, ForkSharedConversationErrors, ForkSharedConversationResponses, GenerateChatConversationTitleData, GenerateChatConversationTitleErrors, GenerateChatConversationTitleResponses, GetAgentData, GetAgentDelegationsData, GetAgentDelegationsErrors, GetAgentDelegationsResponses, GetAgentEmailAddressData, GetAgentEmailAddressErrors, GetAgentEmailAddressResponses, GetAgentErrors, GetAgentResponses, GetAgentsData, GetAgentsErrors, GetAgentsResponses, GetAgentStatisticsData, GetAgentStatisticsErrors, GetAgentStatisticsResponses, GetAgentToolsData, GetAgentToolsErrors, GetAgentToolsResponses, GetAgentVersionsData, GetAgentVersionsErrors, GetAgentVersionsResponses, GetAllAgentsData, GetAllAgentsErrors, GetAllAgentsResponses, GetAllAgentToolsData, GetAllAgentToolsErrors, GetAllAgentToolsResponses, GetAllDelegationConnectionsData, GetAllDelegationConnectionsErrors, GetAllDelegationConnectionsResponses, GetAllVirtualApiKeysData, GetAllVirtualApiKeysErrors, GetAllVirtualApiKeysResponses, GetApiAuthBy__Data, GetApiAuthBy__Responses, GetApiAuthOauth2AuthorizeData, GetApiAuthOauth2AuthorizeResponses, GetAvailableChatApiKeysData, GetAvailableChatApiKeysErrors, GetAvailableChatApiKeysResponses, GetChatAgentMcpToolsData, GetChatAgentMcpToolsErrors, GetChatAgentMcpToolsResponses, GetChatApiKeyData, GetChatApiKeyErrors, GetChatApiKeyResponses, GetChatApiKeysData, GetChatApiKeysErrors, GetChatApiKeysResponses, GetChatConversationData, GetChatConversationErrors, GetChatConversationResponses, GetChatConversationsData, GetChatConversationsErrors, GetChatConversationsResponses, GetChatModelsData, GetChatModelsErrors, GetChatModelsResponses, GetChatOpsStatusData, GetChatOpsStatusErrors, GetChatOpsStatusResponses, GetConfigData, GetConfigResponses, GetConnectorData, GetConnectorErrors, GetConnectorKnowledgeBasesData, GetConnectorKnowledgeBasesErrors, GetConnectorKnowledgeBasesResponses, GetConnectorResponses, GetConnectorRunData, GetConnectorRunErrors, GetConnectorRunResponses, GetConnectorRunsData, GetConnectorRunsErrors, GetConnectorRunsResponses, GetConnectorsData, GetConnectorsErrors, GetConnectorsResponses, GetConversationEnabledToolsData, GetConversationEnabledToolsErrors, GetConversationEnabledToolsResponses, GetConversationShareData, GetConversationShareErrors, GetConversationShareResponses, GetCostSavingsStatisticsData, GetCostSavingsStatisticsErrors, GetCostSavingsStatisticsResponses, GetDefaultCredentialsStatusData, GetDefaultCredentialsStatusErrors, GetDefaultCredentialsStatusResponses, GetDefaultDualLlmConfigData, GetDefaultDualLlmConfigErrors, GetDefaultDualLlmConfigResponses, GetDefaultLlmProxyData, GetDefaultLlmProxyErrors, GetDefaultLlmProxyResponses, GetDefaultMcpGatewayData, GetDefaultMcpGatewayErrors, GetDefaultMcpGatewayResponses, GetDeploymentYamlPreviewData, GetDeploymentYamlPreviewErrors, GetDeploymentYamlPreviewResponses, GetDualLlmConfigData, GetDualLlmConfigErrors, GetDualLlmConfigResponses, GetDualLlmConfigsData, GetDualLlmConfigsErrors, GetDualLlmConfigsResponses, GetDualLlmResultByToolCallIdData, GetDualLlmResultByToolCallIdErrors, GetDualLlmResultByToolCallIdResponses, GetDualLlmResultsByInteractionData, GetDualLlmResultsByInteractionErrors, GetDualLlmResultsByInteractionResponses, GetHealthData, GetHealthResponses, GetIdentityProviderData, GetIdentityProviderErrors, GetIdentityProviderIdpLogoutUrlData, GetIdentityProviderIdpLogoutUrlErrors, GetIdentityProviderIdpLogoutUrlResponses, GetIdentityProviderResponses, GetIdentityProvidersData, GetIdentityProvidersErrors, GetIdentityProvidersResponses, GetIncomingEmailStatusData, GetIncomingEmailStatusErrors, GetIncomingEmailStatusResponses, GetInteractionData, GetInteractionErrors, GetInteractionResponses, GetInteractionsData, GetInteractionsErrors, GetInteractionSessionsData, GetInteractionSessionsErrors, GetInteractionSessionsResponses, GetInteractionsResponses, GetInternalMcpCatalogData, GetInternalMcpCatalogErrors, GetInternalMcpCatalogItemData, GetInternalMcpCatalogItemErrors, GetInternalMcpCatalogItemResponses, GetInternalMcpCatalogLabelKeysData, GetInternalMcpCatalogLabelKeysErrors, GetInternalMcpCatalogLabelKeysResponses, GetInternalMcpCatalogLabelValuesData, GetInternalMcpCatalogLabelValuesErrors, GetInternalMcpCatalogLabelValuesResponses, GetInternalMcpCatalogResponses, GetInternalMcpCatalogToolsData, GetInternalMcpCatalogToolsErrors, GetInternalMcpCatalogToolsResponses, GetK8sImagePullSecretsData, GetK8sImagePullSecretsErrors, GetK8sImagePullSecretsResponses, GetKnowledgeBaseData, GetKnowledgeBaseErrors, GetKnowledgeBaseHealthData, GetKnowledgeBaseHealthErrors, GetKnowledgeBaseHealthResponses, GetKnowledgeBaseResponses, GetKnowledgeBasesData, GetKnowledgeBasesErrors, GetKnowledgeBasesResponses, GetLabelKeysData, GetLabelKeysErrors, GetLabelKeysResponses, GetLabelValuesData, GetLabelValuesErrors, GetLabelValuesResponses, GetLimitData, GetLimitErrors, GetLimitResponses, GetLimitsData, GetLimitsErrors, GetLimitsResponses, GetMcpServerData, GetMcpServerErrors, GetMcpServerInstallationRequestData, GetMcpServerInstallationRequestErrors, GetMcpServerInstallationRequestResponses, GetMcpServerInstallationRequestsData, GetMcpServerInstallationRequestsErrors, GetMcpServerInstallationRequestsResponses, GetMcpServerInstallationStatusData, GetMcpServerInstallationStatusErrors, GetMcpServerInstallationStatusResponses, GetMcpServerResponses, GetMcpServersData, GetMcpServersErrors, GetMcpServersResponses, GetMcpServerToolsData, GetMcpServerToolsErrors, GetMcpServerToolsResponses, GetMcpToolCallData, GetMcpToolCallErrors, GetMcpToolCallResponses, GetMcpToolCallsData, GetMcpToolCallsErrors, GetMcpToolCallsResponses, GetMemberDefaultAgentData, GetMemberDefaultAgentErrors, GetMemberDefaultAgentResponses, GetMemberSignupStatusData, GetMemberSignupStatusErrors, GetMemberSignupStatusResponses, GetModelStatisticsData, GetModelStatisticsErrors, GetModelStatisticsResponses, GetModelsWithApiKeysData, GetModelsWithApiKeysErrors, GetModelsWithApiKeysResponses, GetOAuthClientInfoData, GetOAuthClientInfoResponses, GetOnboardingStatusData, GetOnboardingStatusErrors, GetOnboardingStatusResponses, GetOperatorsData, GetOperatorsErrors, GetOperatorsResponses, GetOptimizationRulesData, GetOptimizationRulesErrors, GetOptimizationRulesResponses, GetOrganizationData, GetOrganizationErrors, GetOrganizationMembersData, GetOrganizationMembersErrors, GetOrganizationMembersResponses, GetOrganizationResponses, GetOverviewStatisticsData, GetOverviewStatisticsErrors, GetOverviewStatisticsResponses, GetPublicAppearanceData, GetPublicAppearanceErrors, GetPublicAppearanceResponses, GetPublicIdentityProvidersData, GetPublicIdentityProvidersErrors, GetPublicIdentityProvidersResponses, GetReadyData, GetReadyErrors, GetReadyResponses, GetRoleData, GetRoleErrors, GetRoleResponses, GetRolesData, GetRolesErrors, GetRolesResponses, GetSecretData, GetSecretErrors, GetSecretResponses, GetSecretsTypeData, GetSecretsTypeErrors, GetSecretsTypeResponses, GetSharedConversationData, GetSharedConversationErrors, GetSharedConversationResponses, GetTeamData, GetTeamErrors, GetTeamExternalGroupsData, GetTeamExternalGroupsErrors, GetTeamExternalGroupsResponses, GetTeamMembersData, GetTeamMembersErrors, GetTeamMembersResponses, GetTeamResponses, GetTeamsData, GetTeamsErrors, GetTeamsResponses, GetTeamStatisticsData, GetTeamStatisticsErrors, GetTeamStatisticsResponses, GetTeamVaultFolderData, GetTeamVaultFolderErrors, GetTeamVaultFolderResponses, GetTeamVaultSecretKeysData, GetTeamVaultSecretKeysErrors, GetTeamVaultSecretKeysResponses, GetTokensData, GetTokensErrors, GetTokensResponses, GetTokenValueData, GetTokenValueErrors, GetTokenValueResponses, GetToolInvocationPoliciesData, GetToolInvocationPoliciesErrors, GetToolInvocationPoliciesResponses, GetToolInvocationPolicyData, GetToolInvocationPolicyErrors, GetToolInvocationPolicyResponses, GetToolsData, GetToolsErrors, GetToolsResponses, GetToolsWithAssignmentsData, GetToolsWithAssignmentsErrors, GetToolsWithAssignmentsResponses, GetTrustedDataPoliciesData, GetTrustedDataPoliciesErrors, GetTrustedDataPoliciesResponses, GetTrustedDataPolicyData, GetTrustedDataPolicyErrors, GetTrustedDataPolicyResponses, GetUniqueExternalAgentIdsData, GetUniqueExternalAgentIdsErrors, GetUniqueExternalAgentIdsResponses, GetUniqueUserIdsData, GetUniqueUserIdsErrors, GetUniqueUserIdsResponses, GetUserPermissionsData, GetUserPermissionsErrors, GetUserPermissionsResponses, GetUserTokenData, GetUserTokenErrors, GetUserTokenResponses, GetUserTokenValueData, GetUserTokenValueErrors, GetUserTokenValueResponses, GetV1A2aByAgentIdWellKnownAgentJsonData, GetV1A2aByAgentIdWellKnownAgentJsonResponses, GetV1McpByProfileIdData, GetV1McpByProfileIdErrors, GetV1McpByProfileIdResponses, GetVirtualApiKeysData, GetVirtualApiKeysErrors, GetVirtualApiKeysResponses, GetWellKnownOauthAuthorizationServerData, GetWellKnownOauthAuthorizationServerResponses, GetWellKnownOauthProtectedResourceBy__Data, GetWellKnownOauthProtectedResourceBy__Responses, GroqChatCompletionsWithAgentData, GroqChatCompletionsWithAgentErrors, GroqChatCompletionsWithAgentResponses, GroqChatCompletionsWithDefaultAgentData, GroqChatCompletionsWithDefaultAgentErrors, GroqChatCompletionsWithDefaultAgentResponses, HandleOAuthCallbackData, HandleOAuthCallbackErrors, HandleOAuthCallbackResponses, InitiateOAuthData, InitiateOAuthErrors, InitiateOAuthResponses, InspectMcpServerData, InspectMcpServerErrors, InspectMcpServerResponses, InstallMcpServerData, InstallMcpServerErrors, InstallMcpServerResponses, ListChatOpsBindingsData, ListChatOpsBindingsErrors, ListChatOpsBindingsResponses, ListTeamVaultFolderSecretsData, ListTeamVaultFolderSecretsErrors, ListTeamVaultFolderSecretsResponses, MinimaxChatCompletionsWithAgentData, MinimaxChatCompletionsWithAgentErrors, MinimaxChatCompletionsWithAgentResponses, MinimaxChatCompletionsWithDefaultAgentData, MinimaxChatCompletionsWithDefaultAgentErrors, MinimaxChatCompletionsWithDefaultAgentResponses, MistralChatCompletionsWithAgentData, MistralChatCompletionsWithAgentErrors, MistralChatCompletionsWithAgentResponses, MistralChatCompletionsWithDefaultAgentData, MistralChatCompletionsWithDefaultAgentErrors, MistralChatCompletionsWithDefaultAgentResponses, OllamaChatCompletionsWithAgentData, OllamaChatCompletionsWithAgentErrors, OllamaChatCompletionsWithAgentResponses, OllamaChatCompletionsWithDefaultAgentData, OllamaChatCompletionsWithDefaultAgentErrors, OllamaChatCompletionsWithDefaultAgentResponses, OpenAiChatCompletionsWithAgentData, OpenAiChatCompletionsWithAgentErrors, OpenAiChatCompletionsWithAgentResponses, OpenAiChatCompletionsWithDefaultAgentData, OpenAiChatCompletionsWithDefaultAgentErrors, OpenAiChatCompletionsWithDefaultAgentResponses, OpenrouterChatCompletionsWithAgentData, OpenrouterChatCompletionsWithAgentErrors, OpenrouterChatCompletionsWithAgentResponses, OpenrouterChatCompletionsWithDefaultAgentData, OpenrouterChatCompletionsWithDefaultAgentErrors, OpenrouterChatCompletionsWithDefaultAgentResponses, PerplexityChatCompletionsWithAgentData, PerplexityChatCompletionsWithAgentErrors, PerplexityChatCompletionsWithAgentResponses, PerplexityChatCompletionsWithDefaultAgentData, PerplexityChatCompletionsWithDefaultAgentErrors, PerplexityChatCompletionsWithDefaultAgentResponses, PostApiAuthBy__Data, PostApiAuthBy__Responses, PostApiAuthOauth2RegisterData, PostApiAuthOauth2RegisterResponses, PostApiAuthOauth2TokenData, PostApiAuthOauth2TokenResponses, PostApiAuthOrganizationRemoveMemberData, PostApiAuthOrganizationRemoveMemberResponses, PostApiWebhooksChatopsMsTeamsData, PostApiWebhooksChatopsMsTeamsErrors, PostApiWebhooksChatopsMsTeamsResponses, PostApiWebhooksChatopsSlackData, PostApiWebhooksChatopsSlackErrors, PostApiWebhooksChatopsSlackInteractiveData, PostApiWebhooksChatopsSlackInteractiveErrors, PostApiWebhooksChatopsSlackInteractiveResponses, PostApiWebhooksChatopsSlackResponses, PostApiWebhooksChatopsSlackSlashCommandData, PostApiWebhooksChatopsSlackSlashCommandErrors, PostApiWebhooksChatopsSlackSlashCommandResponses, PostApiWebhooksIncomingEmailData, PostApiWebhooksIncomingEmailErrors, PostApiWebhooksIncomingEmailResponses, PostV1A2aByAgentIdData, PostV1A2aByAgentIdResponses, PostV1GeminiByAgentIdV1BetaModelsByModelGenerateContentData, PostV1GeminiByAgentIdV1BetaModelsByModelGenerateContentErrors, PostV1GeminiByAgentIdV1BetaModelsByModelGenerateContentResponses, PostV1GeminiByAgentIdV1BetaModelsByModelStreamGenerateContentData, PostV1GeminiByAgentIdV1BetaModelsByModelStreamGenerateContentErrors, PostV1GeminiV1BetaModelsByModelGenerateContentData, PostV1GeminiV1BetaModelsByModelGenerateContentErrors, PostV1GeminiV1BetaModelsByModelGenerateContentResponses, PostV1GeminiV1BetaModelsByModelStreamGenerateContentData, PostV1GeminiV1BetaModelsByModelStreamGenerateContentErrors, PostV1McpByProfileIdData, PostV1McpByProfileIdResponses, ReauthenticateMcpServerData, ReauthenticateMcpServerErrors, ReauthenticateMcpServerResponses, RefreshChatOpsChannelDiscoveryData, RefreshChatOpsChannelDiscoveryErrors, RefreshChatOpsChannelDiscoveryResponses, ReinstallMcpServerData, ReinstallMcpServerErrors, ReinstallMcpServerResponses, RemoveTeamExternalGroupData, RemoveTeamExternalGroupErrors, RemoveTeamExternalGroupResponses, RemoveTeamMemberData, RemoveTeamMemberErrors, RemoveTeamMemberResponses, RenewIncomingEmailSubscriptionData, RenewIncomingEmailSubscriptionErrors, RenewIncomingEmailSubscriptionResponses, ResetDeploymentYamlData, ResetDeploymentYamlErrors, ResetDeploymentYamlResponses, RollbackAgentData, RollbackAgentErrors, RollbackAgentResponses, RotateTokenData, RotateTokenErrors, RotateTokenResponses, RotateUserTokenData, RotateUserTokenErrors, RotateUserTokenResponses, SetTeamVaultFolderData, SetTeamVaultFolderErrors, SetTeamVaultFolderResponses, SetupIncomingEmailWebhookData, SetupIncomingEmailWebhookErrors, SetupIncomingEmailWebhookResponses, ShareConversationData, ShareConversationErrors, ShareConversationResponses, StopChatStreamData, StopChatStreamErrors, StopChatStreamResponses, StreamChatData, StreamChatErrors, SubmitOAuthConsentData, SubmitOAuthConsentResponses, SyncAgentDelegationsData, SyncAgentDelegationsErrors, SyncAgentDelegationsResponses, SyncChatModelsData, SyncChatModelsErrors, SyncChatModelsResponses, SyncConnectorData, SyncConnectorErrors, SyncConnectorResponses, TestConnectorConnectionData, TestConnectorConnectionErrors, TestConnectorConnectionResponses, UnassignConnectorFromKnowledgeBaseData, UnassignConnectorFromKnowledgeBaseErrors, UnassignConnectorFromKnowledgeBaseResponses, UnassignToolFromAgentData, UnassignToolFromAgentErrors, UnassignToolFromAgentResponses, UnshareConversationData, UnshareConversationErrors, UnshareConversationResponses, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponses, UpdateAgentToolData, UpdateAgentToolErrors, UpdateAgentToolResponses, UpdateAppearanceData, UpdateAppearanceErrors, UpdateAppearanceResponses, UpdateChatApiKeyData, UpdateChatApiKeyErrors, UpdateChatApiKeyResponses, UpdateChatConversationData, UpdateChatConversationErrors, UpdateChatConversationResponses, UpdateChatMessageData, UpdateChatMessageErrors, UpdateChatMessageResponses, UpdateChatOpsBindingData, UpdateChatOpsBindingErrors, UpdateChatOpsBindingResponses, UpdateChatOpsConfigInQuickstartData, UpdateChatOpsConfigInQuickstartErrors, UpdateChatOpsConfigInQuickstartResponses, UpdateConnectorData, UpdateConnectorErrors, UpdateConnectorResponses, UpdateConversationEnabledToolsData, UpdateConversationEnabledToolsErrors, UpdateConversationEnabledToolsResponses, UpdateDualLlmConfigData, UpdateDualLlmConfigErrors, UpdateDualLlmConfigResponses, UpdateIdentityProviderData, UpdateIdentityProviderErrors, UpdateIdentityProviderResponses, UpdateInternalMcpCatalogItemData, UpdateInternalMcpCatalogItemErrors, UpdateInternalMcpCatalogItemResponses, UpdateKnowledgeBaseData, UpdateKnowledgeBaseErrors, UpdateKnowledgeBaseResponses, UpdateKnowledgeSettingsData, UpdateKnowledgeSettingsErrors, UpdateKnowledgeSettingsResponses, UpdateLimitData, UpdateLimitErrors, UpdateLimitResponses, UpdateLlmSettingsData, UpdateLlmSettingsErrors, UpdateLlmSettingsResponses, UpdateMcpServerInstallationRequestData, UpdateMcpServerInstallationRequestErrors, UpdateMcpServerInstallationRequestResponses, UpdateMemberDefaultAgentData, UpdateMemberDefaultAgentErrors, UpdateMemberDefaultAgentResponses, UpdateModelPricingData, UpdateModelPricingErrors, UpdateModelPricingResponses, UpdateOptimizationRuleData, UpdateOptimizationRuleErrors, UpdateOptimizationRuleResponses, UpdateRoleData, UpdateRoleErrors, UpdateRoleResponses, UpdateSecuritySettingsData, UpdateSecuritySettingsErrors, UpdateSecuritySettingsResponses, UpdateSlackChatOpsConfigData, UpdateSlackChatOpsConfigErrors, UpdateSlackChatOpsConfigResponses, UpdateTeamData, UpdateTeamErrors, UpdateTeamResponses, UpdateToolInvocationPolicyData, UpdateToolInvocationPolicyErrors, UpdateToolInvocationPolicyResponses, UpdateTrustedDataPolicyData, UpdateTrustedDataPolicyErrors, UpdateTrustedDataPolicyResponses, ValidateDeploymentYamlData, ValidateDeploymentYamlErrors, ValidateDeploymentYamlResponses, VllmChatCompletionsWithAgentData, VllmChatCompletionsWithAgentErrors, VllmChatCompletionsWithAgentResponses, VllmChatCompletionsWithDefaultAgentData, VllmChatCompletionsWithDefaultAgentErrors, VllmChatCompletionsWithDefaultAgentResponses, XaiChatCompletionsWithAgentData, XaiChatCompletionsWithAgentErrors, XaiChatCompletionsWithAgentResponses, XaiChatCompletionsWithDefaultAgentData, XaiChatCompletionsWithDefaultAgentErrors, XaiChatCompletionsWithDefaultAgentResponses, ZhipuaiChatCompletionsWithAgentData, ZhipuaiChatCompletionsWithAgentErrors, ZhipuaiChatCompletionsWithAgentResponses, ZhipuaiChatCompletionsWithDefaultAgentData, ZhipuaiChatCompletionsWithDefaultAgentErrors, ZhipuaiChatCompletionsWithDefaultAgentResponses } from './types.gen'; +import type { AddMcpServerInstallationRequestNoteData, AddMcpServerInstallationRequestNoteErrors, AddMcpServerInstallationRequestNoteResponses, AddTeamExternalGroupData, AddTeamExternalGroupErrors, AddTeamExternalGroupResponses, AddTeamMemberData, AddTeamMemberErrors, AddTeamMemberResponses, AnthropicMessagesWithAgentData, AnthropicMessagesWithAgentErrors, AnthropicMessagesWithAgentResponses, AnthropicMessagesWithDefaultAgentData, AnthropicMessagesWithDefaultAgentErrors, AnthropicMessagesWithDefaultAgentResponses, ApproveMcpServerInstallationRequestData, ApproveMcpServerInstallationRequestErrors, ApproveMcpServerInstallationRequestResponses, AssignConnectorToKnowledgeBasesData, AssignConnectorToKnowledgeBasesErrors, AssignConnectorToKnowledgeBasesResponses, AssignToolToAgentData, AssignToolToAgentErrors, AssignToolToAgentResponses, AutoConfigureAgentToolPoliciesData, AutoConfigureAgentToolPoliciesErrors, AutoConfigureAgentToolPoliciesResponses, BedrockConverseStreamWithAgentAndModelData, BedrockConverseStreamWithAgentAndModelResponses, BedrockConverseStreamWithAgentData, BedrockConverseStreamWithAgentResponses, BedrockConverseStreamWithDefaultAgentData, BedrockConverseStreamWithDefaultAgentResponses, BedrockConverseWithAgentAndModelData, BedrockConverseWithAgentAndModelErrors, BedrockConverseWithAgentAndModelResponses, BedrockConverseWithAgentData, BedrockConverseWithAgentErrors, BedrockConverseWithAgentResponses, BedrockConverseWithDefaultAgentData, BedrockConverseWithDefaultAgentErrors, BedrockConverseWithDefaultAgentResponses, BulkAssignToolsData, BulkAssignToolsErrors, BulkAssignToolsResponses, BulkUpdateChatOpsBindingsData, BulkUpdateChatOpsBindingsErrors, BulkUpdateChatOpsBindingsResponses, BulkUpsertDefaultCallPolicyData, BulkUpsertDefaultCallPolicyErrors, BulkUpsertDefaultCallPolicyResponses, BulkUpsertDefaultResultPolicyData, BulkUpsertDefaultResultPolicyErrors, BulkUpsertDefaultResultPolicyResponses, CerebrasChatCompletionsWithAgentData, CerebrasChatCompletionsWithAgentErrors, CerebrasChatCompletionsWithAgentResponses, CerebrasChatCompletionsWithDefaultAgentData, CerebrasChatCompletionsWithDefaultAgentErrors, CerebrasChatCompletionsWithDefaultAgentResponses, CheckInvitationData, CheckInvitationErrors, CheckInvitationResponses, CheckSecretsConnectivityData, CheckSecretsConnectivityErrors, CheckSecretsConnectivityResponses, CheckTeamVaultFolderConnectivityData, CheckTeamVaultFolderConnectivityErrors, CheckTeamVaultFolderConnectivityResponses, CohereChatWithAgentData, CohereChatWithAgentErrors, CohereChatWithAgentResponses, CohereChatWithDefaultAgentData, CohereChatWithDefaultAgentErrors, CohereChatWithDefaultAgentResponses, CompleteOnboardingData, CompleteOnboardingErrors, CompleteOnboardingResponses, CreateAgentData, CreateAgentErrors, CreateAgentResponses, CreateChatApiKeyData, CreateChatApiKeyErrors, CreateChatApiKeyResponses, CreateChatConversationData, CreateChatConversationErrors, CreateChatConversationResponses, CreateChatOpsDmBindingData, CreateChatOpsDmBindingErrors, CreateChatOpsDmBindingResponses, CreateConnectorData, CreateConnectorErrors, CreateConnectorResponses, CreateDualLlmConfigData, CreateDualLlmConfigErrors, CreateDualLlmConfigResponses, CreateIdentityProviderData, CreateIdentityProviderErrors, CreateIdentityProviderResponses, CreateInternalMcpCatalogItemData, CreateInternalMcpCatalogItemErrors, CreateInternalMcpCatalogItemResponses, CreateKnowledgeBaseData, CreateKnowledgeBaseErrors, CreateKnowledgeBaseResponses, CreateLimitData, CreateLimitErrors, CreateLimitResponses, CreateMcpServerInstallationRequestData, CreateMcpServerInstallationRequestErrors, CreateMcpServerInstallationRequestResponses, CreateOptimizationRuleData, CreateOptimizationRuleErrors, CreateOptimizationRuleResponses, CreateRoleData, CreateRoleErrors, CreateRoleResponses, CreateTeamData, CreateTeamErrors, CreateTeamResponses, CreateToolInvocationPolicyData, CreateToolInvocationPolicyErrors, CreateToolInvocationPolicyResponses, CreateTrustedDataPolicyData, CreateTrustedDataPolicyErrors, CreateTrustedDataPolicyResponses, CreateVirtualApiKeyData, CreateVirtualApiKeyErrors, CreateVirtualApiKeyResponses, DeclineMcpServerInstallationRequestData, DeclineMcpServerInstallationRequestErrors, DeclineMcpServerInstallationRequestResponses, DeepseekChatCompletionsWithAgentData, DeepseekChatCompletionsWithAgentErrors, DeepseekChatCompletionsWithAgentResponses, DeepseekChatCompletionsWithDefaultAgentData, DeepseekChatCompletionsWithDefaultAgentErrors, DeepseekChatCompletionsWithDefaultAgentResponses, DeleteAgentData, DeleteAgentDelegationData, DeleteAgentDelegationErrors, DeleteAgentDelegationResponses, DeleteAgentErrors, DeleteAgentResponses, DeleteChatApiKeyData, DeleteChatApiKeyErrors, DeleteChatApiKeyResponses, DeleteChatConversationData, DeleteChatConversationErrors, DeleteChatConversationResponses, DeleteChatOpsBindingData, DeleteChatOpsBindingErrors, DeleteChatOpsBindingResponses, DeleteConnectorData, DeleteConnectorErrors, DeleteConnectorResponses, DeleteConversationEnabledToolsData, DeleteConversationEnabledToolsErrors, DeleteConversationEnabledToolsResponses, DeleteDualLlmConfigData, DeleteDualLlmConfigErrors, DeleteDualLlmConfigResponses, DeleteIdentityProviderData, DeleteIdentityProviderErrors, DeleteIdentityProviderResponses, DeleteIncomingEmailSubscriptionData, DeleteIncomingEmailSubscriptionErrors, DeleteIncomingEmailSubscriptionResponses, DeleteInternalMcpCatalogItemBySlugData, DeleteInternalMcpCatalogItemBySlugErrors, DeleteInternalMcpCatalogItemBySlugResponses, DeleteInternalMcpCatalogItemData, DeleteInternalMcpCatalogItemErrors, DeleteInternalMcpCatalogItemResponses, DeleteKnowledgeBaseData, DeleteKnowledgeBaseErrors, DeleteKnowledgeBaseResponses, DeleteLimitData, DeleteLimitErrors, DeleteLimitResponses, DeleteMcpServerData, DeleteMcpServerErrors, DeleteMcpServerInstallationRequestData, DeleteMcpServerInstallationRequestErrors, DeleteMcpServerInstallationRequestResponses, DeleteMcpServerResponses, DeleteOptimizationRuleData, DeleteOptimizationRuleErrors, DeleteOptimizationRuleResponses, DeletePendingSignupMemberData, DeletePendingSignupMemberErrors, DeletePendingSignupMemberResponses, DeleteRoleData, DeleteRoleErrors, DeleteRoleResponses, DeleteTeamData, DeleteTeamErrors, DeleteTeamResponses, DeleteTeamVaultFolderData, DeleteTeamVaultFolderErrors, DeleteTeamVaultFolderResponses, DeleteToolData, DeleteToolErrors, DeleteToolInvocationPolicyData, DeleteToolInvocationPolicyErrors, DeleteToolInvocationPolicyResponses, DeleteToolResponses, DeleteTrustedDataPolicyData, DeleteTrustedDataPolicyErrors, DeleteTrustedDataPolicyResponses, DeleteVirtualApiKeyData, DeleteVirtualApiKeyErrors, DeleteVirtualApiKeyResponses, ForkSharedConversationData, ForkSharedConversationErrors, ForkSharedConversationResponses, GenerateChatConversationTitleData, GenerateChatConversationTitleErrors, GenerateChatConversationTitleResponses, GetAgentData, GetAgentDelegationsData, GetAgentDelegationsErrors, GetAgentDelegationsResponses, GetAgentEmailAddressData, GetAgentEmailAddressErrors, GetAgentEmailAddressResponses, GetAgentErrors, GetAgentResponses, GetAgentsData, GetAgentsErrors, GetAgentsResponses, GetAgentStatisticsData, GetAgentStatisticsErrors, GetAgentStatisticsResponses, GetAgentToolsData, GetAgentToolsErrors, GetAgentToolsResponses, GetAgentVersionsData, GetAgentVersionsErrors, GetAgentVersionsResponses, GetAllAgentsData, GetAllAgentsErrors, GetAllAgentsResponses, GetAllAgentToolsData, GetAllAgentToolsErrors, GetAllAgentToolsResponses, GetAllDelegationConnectionsData, GetAllDelegationConnectionsErrors, GetAllDelegationConnectionsResponses, GetAllVirtualApiKeysData, GetAllVirtualApiKeysErrors, GetAllVirtualApiKeysResponses, GetApiAuthBy__Data, GetApiAuthBy__Responses, GetApiAuthOauth2AuthorizeData, GetApiAuthOauth2AuthorizeResponses, GetAvailableChatApiKeysData, GetAvailableChatApiKeysErrors, GetAvailableChatApiKeysResponses, GetChatAgentMcpToolsData, GetChatAgentMcpToolsErrors, GetChatAgentMcpToolsResponses, GetChatApiKeyData, GetChatApiKeyErrors, GetChatApiKeyResponses, GetChatApiKeysData, GetChatApiKeysErrors, GetChatApiKeysResponses, GetChatConversationData, GetChatConversationErrors, GetChatConversationResponses, GetChatConversationsData, GetChatConversationsErrors, GetChatConversationsResponses, GetChatModelsData, GetChatModelsErrors, GetChatModelsResponses, GetChatOpsStatusData, GetChatOpsStatusErrors, GetChatOpsStatusResponses, GetConfigData, GetConfigResponses, GetConnectorData, GetConnectorErrors, GetConnectorKnowledgeBasesData, GetConnectorKnowledgeBasesErrors, GetConnectorKnowledgeBasesResponses, GetConnectorResponses, GetConnectorRunData, GetConnectorRunErrors, GetConnectorRunResponses, GetConnectorRunsData, GetConnectorRunsErrors, GetConnectorRunsResponses, GetConnectorsData, GetConnectorsErrors, GetConnectorsResponses, GetConversationEnabledToolsData, GetConversationEnabledToolsErrors, GetConversationEnabledToolsResponses, GetConversationShareData, GetConversationShareErrors, GetConversationShareResponses, GetCostSavingsStatisticsData, GetCostSavingsStatisticsErrors, GetCostSavingsStatisticsResponses, GetDefaultCredentialsStatusData, GetDefaultCredentialsStatusErrors, GetDefaultCredentialsStatusResponses, GetDefaultDualLlmConfigData, GetDefaultDualLlmConfigErrors, GetDefaultDualLlmConfigResponses, GetDefaultLlmProxyData, GetDefaultLlmProxyErrors, GetDefaultLlmProxyResponses, GetDefaultMcpGatewayData, GetDefaultMcpGatewayErrors, GetDefaultMcpGatewayResponses, GetDeploymentYamlPreviewData, GetDeploymentYamlPreviewErrors, GetDeploymentYamlPreviewResponses, GetDualLlmConfigData, GetDualLlmConfigErrors, GetDualLlmConfigResponses, GetDualLlmConfigsData, GetDualLlmConfigsErrors, GetDualLlmConfigsResponses, GetDualLlmResultByToolCallIdData, GetDualLlmResultByToolCallIdErrors, GetDualLlmResultByToolCallIdResponses, GetDualLlmResultsByInteractionData, GetDualLlmResultsByInteractionErrors, GetDualLlmResultsByInteractionResponses, GetHealthData, GetHealthResponses, GetIdentityProviderData, GetIdentityProviderErrors, GetIdentityProviderIdpLogoutUrlData, GetIdentityProviderIdpLogoutUrlErrors, GetIdentityProviderIdpLogoutUrlResponses, GetIdentityProviderResponses, GetIdentityProvidersData, GetIdentityProvidersErrors, GetIdentityProvidersResponses, GetIncomingEmailStatusData, GetIncomingEmailStatusErrors, GetIncomingEmailStatusResponses, GetInteractionData, GetInteractionErrors, GetInteractionResponses, GetInteractionsData, GetInteractionsErrors, GetInteractionSessionsData, GetInteractionSessionsErrors, GetInteractionSessionsResponses, GetInteractionsResponses, GetInternalMcpCatalogData, GetInternalMcpCatalogErrors, GetInternalMcpCatalogItemData, GetInternalMcpCatalogItemErrors, GetInternalMcpCatalogItemResponses, GetInternalMcpCatalogLabelKeysData, GetInternalMcpCatalogLabelKeysErrors, GetInternalMcpCatalogLabelKeysResponses, GetInternalMcpCatalogLabelValuesData, GetInternalMcpCatalogLabelValuesErrors, GetInternalMcpCatalogLabelValuesResponses, GetInternalMcpCatalogResponses, GetInternalMcpCatalogToolsData, GetInternalMcpCatalogToolsErrors, GetInternalMcpCatalogToolsResponses, GetK8sImagePullSecretsData, GetK8sImagePullSecretsErrors, GetK8sImagePullSecretsResponses, GetKnowledgeBaseData, GetKnowledgeBaseErrors, GetKnowledgeBaseHealthData, GetKnowledgeBaseHealthErrors, GetKnowledgeBaseHealthResponses, GetKnowledgeBaseResponses, GetKnowledgeBasesData, GetKnowledgeBasesErrors, GetKnowledgeBasesResponses, GetLabelKeysData, GetLabelKeysErrors, GetLabelKeysResponses, GetLabelValuesData, GetLabelValuesErrors, GetLabelValuesResponses, GetLimitData, GetLimitErrors, GetLimitResponses, GetLimitsData, GetLimitsErrors, GetLimitsResponses, GetMcpServerData, GetMcpServerErrors, GetMcpServerInstallationRequestData, GetMcpServerInstallationRequestErrors, GetMcpServerInstallationRequestResponses, GetMcpServerInstallationRequestsData, GetMcpServerInstallationRequestsErrors, GetMcpServerInstallationRequestsResponses, GetMcpServerInstallationStatusData, GetMcpServerInstallationStatusErrors, GetMcpServerInstallationStatusResponses, GetMcpServerResponses, GetMcpServersData, GetMcpServersErrors, GetMcpServersResponses, GetMcpServerToolsData, GetMcpServerToolsErrors, GetMcpServerToolsResponses, GetMcpToolCallData, GetMcpToolCallErrors, GetMcpToolCallResponses, GetMcpToolCallsData, GetMcpToolCallsErrors, GetMcpToolCallsResponses, GetMemberDefaultAgentData, GetMemberDefaultAgentErrors, GetMemberDefaultAgentResponses, GetMemberSignupStatusData, GetMemberSignupStatusErrors, GetMemberSignupStatusResponses, GetModelStatisticsData, GetModelStatisticsErrors, GetModelStatisticsResponses, GetModelsWithApiKeysData, GetModelsWithApiKeysErrors, GetModelsWithApiKeysResponses, GetOAuthClientInfoData, GetOAuthClientInfoResponses, GetOnboardingStatusData, GetOnboardingStatusErrors, GetOnboardingStatusResponses, GetOperatorsData, GetOperatorsErrors, GetOperatorsResponses, GetOptimizationRulesData, GetOptimizationRulesErrors, GetOptimizationRulesResponses, GetOrganizationData, GetOrganizationErrors, GetOrganizationMembersData, GetOrganizationMembersErrors, GetOrganizationMembersResponses, GetOrganizationResponses, GetOverviewStatisticsData, GetOverviewStatisticsErrors, GetOverviewStatisticsResponses, GetPublicAppearanceData, GetPublicAppearanceErrors, GetPublicAppearanceResponses, GetPublicIdentityProvidersData, GetPublicIdentityProvidersErrors, GetPublicIdentityProvidersResponses, GetReadyData, GetReadyErrors, GetReadyResponses, GetRoleData, GetRoleErrors, GetRoleResponses, GetRolesData, GetRolesErrors, GetRolesResponses, GetSecretData, GetSecretErrors, GetSecretResponses, GetSecretsTypeData, GetSecretsTypeErrors, GetSecretsTypeResponses, GetSharedConversationData, GetSharedConversationErrors, GetSharedConversationResponses, GetTeamData, GetTeamErrors, GetTeamExternalGroupsData, GetTeamExternalGroupsErrors, GetTeamExternalGroupsResponses, GetTeamMembersData, GetTeamMembersErrors, GetTeamMembersResponses, GetTeamResponses, GetTeamsData, GetTeamsErrors, GetTeamsResponses, GetTeamStatisticsData, GetTeamStatisticsErrors, GetTeamStatisticsResponses, GetTeamVaultFolderData, GetTeamVaultFolderErrors, GetTeamVaultFolderResponses, GetTeamVaultSecretKeysData, GetTeamVaultSecretKeysErrors, GetTeamVaultSecretKeysResponses, GetTokensData, GetTokensErrors, GetTokensResponses, GetTokenValueData, GetTokenValueErrors, GetTokenValueResponses, GetToolInvocationPoliciesData, GetToolInvocationPoliciesErrors, GetToolInvocationPoliciesResponses, GetToolInvocationPolicyData, GetToolInvocationPolicyErrors, GetToolInvocationPolicyResponses, GetToolsData, GetToolsErrors, GetToolsResponses, GetToolsWithAssignmentsData, GetToolsWithAssignmentsErrors, GetToolsWithAssignmentsResponses, GetTrustedDataPoliciesData, GetTrustedDataPoliciesErrors, GetTrustedDataPoliciesResponses, GetTrustedDataPolicyData, GetTrustedDataPolicyErrors, GetTrustedDataPolicyResponses, GetUniqueExternalAgentIdsData, GetUniqueExternalAgentIdsErrors, GetUniqueExternalAgentIdsResponses, GetUniqueUserIdsData, GetUniqueUserIdsErrors, GetUniqueUserIdsResponses, GetUserPermissionsData, GetUserPermissionsErrors, GetUserPermissionsResponses, GetUserTokenData, GetUserTokenErrors, GetUserTokenResponses, GetUserTokenValueData, GetUserTokenValueErrors, GetUserTokenValueResponses, GetV1A2aByAgentIdWellKnownAgentJsonData, GetV1A2aByAgentIdWellKnownAgentJsonResponses, GetV1McpByProfileIdData, GetV1McpByProfileIdErrors, GetV1McpByProfileIdResponses, GetVirtualApiKeysData, GetVirtualApiKeysErrors, GetVirtualApiKeysResponses, GetWellKnownOauthAuthorizationServerData, GetWellKnownOauthAuthorizationServerResponses, GetWellKnownOauthProtectedResourceBy__Data, GetWellKnownOauthProtectedResourceBy__Responses, GroqChatCompletionsWithAgentData, GroqChatCompletionsWithAgentErrors, GroqChatCompletionsWithAgentResponses, GroqChatCompletionsWithDefaultAgentData, GroqChatCompletionsWithDefaultAgentErrors, GroqChatCompletionsWithDefaultAgentResponses, HandleOAuthCallbackData, HandleOAuthCallbackErrors, HandleOAuthCallbackResponses, InitiateOAuthData, InitiateOAuthErrors, InitiateOAuthResponses, InspectMcpServerData, InspectMcpServerErrors, InspectMcpServerResponses, InstallMcpServerData, InstallMcpServerErrors, InstallMcpServerResponses, ListChatOpsBindingsData, ListChatOpsBindingsErrors, ListChatOpsBindingsResponses, ListTeamVaultFolderSecretsData, ListTeamVaultFolderSecretsErrors, ListTeamVaultFolderSecretsResponses, MinimaxChatCompletionsWithAgentData, MinimaxChatCompletionsWithAgentErrors, MinimaxChatCompletionsWithAgentResponses, MinimaxChatCompletionsWithDefaultAgentData, MinimaxChatCompletionsWithDefaultAgentErrors, MinimaxChatCompletionsWithDefaultAgentResponses, MistralChatCompletionsWithAgentData, MistralChatCompletionsWithAgentErrors, MistralChatCompletionsWithAgentResponses, MistralChatCompletionsWithDefaultAgentData, MistralChatCompletionsWithDefaultAgentErrors, MistralChatCompletionsWithDefaultAgentResponses, OllamaChatCompletionsWithAgentData, OllamaChatCompletionsWithAgentErrors, OllamaChatCompletionsWithAgentResponses, OllamaChatCompletionsWithDefaultAgentData, OllamaChatCompletionsWithDefaultAgentErrors, OllamaChatCompletionsWithDefaultAgentResponses, OpenAiChatCompletionsWithAgentData, OpenAiChatCompletionsWithAgentErrors, OpenAiChatCompletionsWithAgentResponses, OpenAiChatCompletionsWithDefaultAgentData, OpenAiChatCompletionsWithDefaultAgentErrors, OpenAiChatCompletionsWithDefaultAgentResponses, OpenrouterChatCompletionsWithAgentData, OpenrouterChatCompletionsWithAgentErrors, OpenrouterChatCompletionsWithAgentResponses, OpenrouterChatCompletionsWithDefaultAgentData, OpenrouterChatCompletionsWithDefaultAgentErrors, OpenrouterChatCompletionsWithDefaultAgentResponses, PerplexityChatCompletionsWithAgentData, PerplexityChatCompletionsWithAgentErrors, PerplexityChatCompletionsWithAgentResponses, PerplexityChatCompletionsWithDefaultAgentData, PerplexityChatCompletionsWithDefaultAgentErrors, PerplexityChatCompletionsWithDefaultAgentResponses, PostApiAuthBy__Data, PostApiAuthBy__Responses, PostApiAuthOauth2RegisterData, PostApiAuthOauth2RegisterResponses, PostApiAuthOauth2TokenData, PostApiAuthOauth2TokenResponses, PostApiAuthOrganizationRemoveMemberData, PostApiAuthOrganizationRemoveMemberResponses, PostApiWebhooksChatopsMsTeamsData, PostApiWebhooksChatopsMsTeamsErrors, PostApiWebhooksChatopsMsTeamsResponses, PostApiWebhooksChatopsSlackData, PostApiWebhooksChatopsSlackErrors, PostApiWebhooksChatopsSlackInteractiveData, PostApiWebhooksChatopsSlackInteractiveErrors, PostApiWebhooksChatopsSlackInteractiveResponses, PostApiWebhooksChatopsSlackResponses, PostApiWebhooksChatopsSlackSlashCommandData, PostApiWebhooksChatopsSlackSlashCommandErrors, PostApiWebhooksChatopsSlackSlashCommandResponses, PostApiWebhooksIncomingEmailData, PostApiWebhooksIncomingEmailErrors, PostApiWebhooksIncomingEmailResponses, PostV1A2aByAgentIdData, PostV1A2aByAgentIdResponses, PostV1GeminiByAgentIdV1BetaModelsByModelGenerateContentData, PostV1GeminiByAgentIdV1BetaModelsByModelGenerateContentErrors, PostV1GeminiByAgentIdV1BetaModelsByModelGenerateContentResponses, PostV1GeminiByAgentIdV1BetaModelsByModelStreamGenerateContentData, PostV1GeminiByAgentIdV1BetaModelsByModelStreamGenerateContentErrors, PostV1GeminiV1BetaModelsByModelGenerateContentData, PostV1GeminiV1BetaModelsByModelGenerateContentErrors, PostV1GeminiV1BetaModelsByModelGenerateContentResponses, PostV1GeminiV1BetaModelsByModelStreamGenerateContentData, PostV1GeminiV1BetaModelsByModelStreamGenerateContentErrors, PostV1McpByProfileIdData, PostV1McpByProfileIdResponses, ReauthenticateMcpServerData, ReauthenticateMcpServerErrors, ReauthenticateMcpServerResponses, RefreshChatOpsChannelDiscoveryData, RefreshChatOpsChannelDiscoveryErrors, RefreshChatOpsChannelDiscoveryResponses, ReinstallMcpServerData, ReinstallMcpServerErrors, ReinstallMcpServerResponses, RemoveTeamExternalGroupData, RemoveTeamExternalGroupErrors, RemoveTeamExternalGroupResponses, RemoveTeamMemberData, RemoveTeamMemberErrors, RemoveTeamMemberResponses, RenewIncomingEmailSubscriptionData, RenewIncomingEmailSubscriptionErrors, RenewIncomingEmailSubscriptionResponses, ResetDeploymentYamlData, ResetDeploymentYamlErrors, ResetDeploymentYamlResponses, RollbackAgentData, RollbackAgentErrors, RollbackAgentResponses, RotateTokenData, RotateTokenErrors, RotateTokenResponses, RotateUserTokenData, RotateUserTokenErrors, RotateUserTokenResponses, SetTeamVaultFolderData, SetTeamVaultFolderErrors, SetTeamVaultFolderResponses, SetupIncomingEmailWebhookData, SetupIncomingEmailWebhookErrors, SetupIncomingEmailWebhookResponses, ShareConversationData, ShareConversationErrors, ShareConversationResponses, StopChatStreamData, StopChatStreamErrors, StopChatStreamResponses, StreamChatData, StreamChatErrors, SubmitOAuthConsentData, SubmitOAuthConsentResponses, SyncAgentDelegationsData, SyncAgentDelegationsErrors, SyncAgentDelegationsResponses, SyncChatModelsData, SyncChatModelsErrors, SyncChatModelsResponses, SyncConnectorData, SyncConnectorErrors, SyncConnectorResponses, TestConnectorConnectionData, TestConnectorConnectionErrors, TestConnectorConnectionResponses, UnassignConnectorFromKnowledgeBaseData, UnassignConnectorFromKnowledgeBaseErrors, UnassignConnectorFromKnowledgeBaseResponses, UnassignToolFromAgentData, UnassignToolFromAgentErrors, UnassignToolFromAgentResponses, UnshareConversationData, UnshareConversationErrors, UnshareConversationResponses, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponses, UpdateAgentToolData, UpdateAgentToolErrors, UpdateAgentToolResponses, UpdateAppearanceData, UpdateAppearanceErrors, UpdateAppearanceResponses, UpdateChatApiKeyData, UpdateChatApiKeyErrors, UpdateChatApiKeyResponses, UpdateChatConversationData, UpdateChatConversationErrors, UpdateChatConversationResponses, UpdateChatMessageData, UpdateChatMessageErrors, UpdateChatMessageResponses, UpdateChatOpsBindingData, UpdateChatOpsBindingErrors, UpdateChatOpsBindingResponses, UpdateChatOpsConfigInQuickstartData, UpdateChatOpsConfigInQuickstartErrors, UpdateChatOpsConfigInQuickstartResponses, UpdateConnectorData, UpdateConnectorErrors, UpdateConnectorResponses, UpdateConversationEnabledToolsData, UpdateConversationEnabledToolsErrors, UpdateConversationEnabledToolsResponses, UpdateDualLlmConfigData, UpdateDualLlmConfigErrors, UpdateDualLlmConfigResponses, UpdateIdentityProviderData, UpdateIdentityProviderErrors, UpdateIdentityProviderResponses, UpdateInternalMcpCatalogItemData, UpdateInternalMcpCatalogItemErrors, UpdateInternalMcpCatalogItemResponses, UpdateKnowledgeBaseData, UpdateKnowledgeBaseErrors, UpdateKnowledgeBaseResponses, UpdateKnowledgeSettingsData, UpdateKnowledgeSettingsErrors, UpdateKnowledgeSettingsResponses, UpdateLimitData, UpdateLimitErrors, UpdateLimitResponses, UpdateLlmSettingsData, UpdateLlmSettingsErrors, UpdateLlmSettingsResponses, UpdateMcpServerInstallationRequestData, UpdateMcpServerInstallationRequestErrors, UpdateMcpServerInstallationRequestResponses, UpdateMemberDefaultAgentData, UpdateMemberDefaultAgentErrors, UpdateMemberDefaultAgentResponses, UpdateModelPricingData, UpdateModelPricingErrors, UpdateModelPricingResponses, UpdateOptimizationRuleData, UpdateOptimizationRuleErrors, UpdateOptimizationRuleResponses, UpdateRoleData, UpdateRoleErrors, UpdateRoleResponses, UpdateSecuritySettingsData, UpdateSecuritySettingsErrors, UpdateSecuritySettingsResponses, UpdateSlackChatOpsConfigData, UpdateSlackChatOpsConfigErrors, UpdateSlackChatOpsConfigResponses, UpdateTeamData, UpdateTeamErrors, UpdateTeamResponses, UpdateToolInvocationPolicyData, UpdateToolInvocationPolicyErrors, UpdateToolInvocationPolicyResponses, UpdateTrustedDataPolicyData, UpdateTrustedDataPolicyErrors, UpdateTrustedDataPolicyResponses, ValidateDeploymentYamlData, ValidateDeploymentYamlErrors, ValidateDeploymentYamlResponses, VllmChatCompletionsWithAgentData, VllmChatCompletionsWithAgentErrors, VllmChatCompletionsWithAgentResponses, VllmChatCompletionsWithDefaultAgentData, VllmChatCompletionsWithDefaultAgentErrors, VllmChatCompletionsWithDefaultAgentResponses, XaiChatCompletionsWithAgentData, XaiChatCompletionsWithAgentErrors, XaiChatCompletionsWithAgentResponses, XaiChatCompletionsWithDefaultAgentData, XaiChatCompletionsWithDefaultAgentErrors, XaiChatCompletionsWithDefaultAgentResponses, ZhipuaiChatCompletionsWithAgentData, ZhipuaiChatCompletionsWithAgentErrors, ZhipuaiChatCompletionsWithAgentResponses, ZhipuaiChatCompletionsWithDefaultAgentData, ZhipuaiChatCompletionsWithDefaultAgentErrors, ZhipuaiChatCompletionsWithDefaultAgentResponses } from './types.gen'; export type Options = Options2 & { /** @@ -1148,9 +1148,9 @@ export const updateInternalMcpCatalogItem = (options: Options) => (options.client ?? client).get({ url: '/api/internal_mcp_catalog/{id}/tools', ...options }); /** - * Delete an Internal MCP catalog item by name + * Delete an Internal MCP catalog item by slug */ -export const deleteInternalMcpCatalogItemByName = (options: Options) => (options.client ?? client).delete({ url: '/api/internal_mcp_catalog/by-name/{name}', ...options }); +export const deleteInternalMcpCatalogItemBySlug = (options: Options) => (options.client ?? client).delete({ url: '/api/internal_mcp_catalog/by-slug/{slug}', ...options }); /** * Generate a deployment YAML template preview for a catalog item diff --git a/platform/shared/hey-api/clients/api/types.gen.ts b/platform/shared/hey-api/clients/api/types.gen.ts index b95d31f968..d879554dc3 100644 --- a/platform/shared/hey-api/clients/api/types.gen.ts +++ b/platform/shared/hey-api/clients/api/types.gen.ts @@ -25391,7 +25391,8 @@ export type GetInternalMcpCatalogResponses = { */ 200: Array<{ id: string; - name: string; + slug: string; + displayName: string; version: string | null; description: string | null; instructions: string | null; @@ -25500,7 +25501,8 @@ export type GetInternalMcpCatalogResponse = GetInternalMcpCatalogResponses[keyof export type CreateInternalMcpCatalogItemData = { body: { id?: string; - name: string; + slug: string; + displayName: string; version?: string | null; description?: string | null; instructions?: string | null; @@ -25668,7 +25670,8 @@ export type CreateInternalMcpCatalogItemResponses = { */ 200: { id: string; - name: string; + slug: string; + displayName: string; version: string | null; description: string | null; instructions: string | null; @@ -25927,7 +25930,8 @@ export type GetInternalMcpCatalogItemResponses = { */ 200: { id: string; - name: string; + slug: string; + displayName: string; version: string | null; description: string | null; instructions: string | null; @@ -26035,7 +26039,8 @@ export type GetInternalMcpCatalogItemResponse = GetInternalMcpCatalogItemRespons export type UpdateInternalMcpCatalogItemData = { body?: { - name?: string; + slug?: string; + displayName?: string; version?: string | null; description?: string | null; instructions?: string | null; @@ -26205,7 +26210,8 @@ export type UpdateInternalMcpCatalogItemResponses = { */ 200: { id: string; - name: string; + slug: string; + displayName: string; version: string | null; description: string | null; instructions: string | null; @@ -26401,16 +26407,16 @@ export type GetInternalMcpCatalogToolsResponses = { export type GetInternalMcpCatalogToolsResponse = GetInternalMcpCatalogToolsResponses[keyof GetInternalMcpCatalogToolsResponses]; -export type DeleteInternalMcpCatalogItemByNameData = { +export type DeleteInternalMcpCatalogItemBySlugData = { body?: never; path: { - name: string; + slug: string; }; query?: never; - url: '/api/internal_mcp_catalog/by-name/{name}'; + url: '/api/internal_mcp_catalog/by-slug/{slug}'; }; -export type DeleteInternalMcpCatalogItemByNameErrors = { +export type DeleteInternalMcpCatalogItemBySlugErrors = { /** * Default Response */ @@ -26467,9 +26473,9 @@ export type DeleteInternalMcpCatalogItemByNameErrors = { }; }; -export type DeleteInternalMcpCatalogItemByNameError = DeleteInternalMcpCatalogItemByNameErrors[keyof DeleteInternalMcpCatalogItemByNameErrors]; +export type DeleteInternalMcpCatalogItemBySlugError = DeleteInternalMcpCatalogItemBySlugErrors[keyof DeleteInternalMcpCatalogItemBySlugErrors]; -export type DeleteInternalMcpCatalogItemByNameResponses = { +export type DeleteInternalMcpCatalogItemBySlugResponses = { /** * Default Response */ @@ -26478,7 +26484,7 @@ export type DeleteInternalMcpCatalogItemByNameResponses = { }; }; -export type DeleteInternalMcpCatalogItemByNameResponse = DeleteInternalMcpCatalogItemByNameResponses[keyof DeleteInternalMcpCatalogItemByNameResponses]; +export type DeleteInternalMcpCatalogItemBySlugResponse = DeleteInternalMcpCatalogItemBySlugResponses[keyof DeleteInternalMcpCatalogItemBySlugResponses]; export type GetDeploymentYamlPreviewData = { body?: never; @@ -30876,7 +30882,7 @@ export type GetMcpServersResponses = { createdAt: string; updatedAt: string; ownerEmail?: string | null; - catalogName?: string | null; + catalogSlug?: string | null; users?: Array; userDetails?: Array<{ userId: string; @@ -31002,7 +31008,7 @@ export type InstallMcpServerResponses = { createdAt: string; updatedAt: string; ownerEmail?: string | null; - catalogName?: string | null; + catalogSlug?: string | null; users?: Array; userDetails?: Array<{ userId: string; @@ -31187,7 +31193,7 @@ export type GetMcpServerResponses = { createdAt: string; updatedAt: string; ownerEmail?: string | null; - catalogName?: string | null; + catalogSlug?: string | null; users?: Array; userDetails?: Array<{ userId: string; @@ -31303,7 +31309,7 @@ export type ReauthenticateMcpServerResponses = { createdAt: string; updatedAt: string; ownerEmail?: string | null; - catalogName?: string | null; + catalogSlug?: string | null; users?: Array; userDetails?: Array<{ userId: string; @@ -31670,7 +31676,7 @@ export type ReinstallMcpServerResponses = { createdAt: string; updatedAt: string; ownerEmail?: string | null; - catalogName?: string | null; + catalogSlug?: string | null; users?: Array; userDetails?: Array<{ userId: string; @@ -36964,7 +36970,7 @@ export type GetToolsResponses = { } | null; catalog: { id: string; - name: string; + slug: string; } | null; }>; }; diff --git a/platform/shared/routes.ts b/platform/shared/routes.ts index 93ee6b04c7..2ef9b9e7fe 100644 --- a/platform/shared/routes.ts +++ b/platform/shared/routes.ts @@ -43,7 +43,7 @@ export const RouteId = { GetInternalMcpCatalogTools: "getInternalMcpCatalogTools", UpdateInternalMcpCatalogItem: "updateInternalMcpCatalogItem", DeleteInternalMcpCatalogItem: "deleteInternalMcpCatalogItem", - DeleteInternalMcpCatalogItemByName: "deleteInternalMcpCatalogItemByName", + DeleteInternalMcpCatalogItemBySlug: "deleteInternalMcpCatalogItemBySlug", GetInternalMcpCatalogLabelKeys: "getInternalMcpCatalogLabelKeys", GetInternalMcpCatalogLabelValues: "getInternalMcpCatalogLabelValues", GetDeploymentYamlPreview: "getDeploymentYamlPreview", From d8ff80a63e3a5e50baeb2e5c585a8f61455d4e19 Mon Sep 17 00:00:00 2001 From: brojd Date: Mon, 9 Mar 2026 22:16:47 +0100 Subject: [PATCH 2/5] slugify catalog Name from frontend forms into catalog.slug --- .../src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts b/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts index dc4bb155a6..19f8c3bd42 100644 --- a/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts +++ b/platform/frontend/src/app/mcp/registry/_parts/mcp-catalog-form.utils.ts @@ -4,6 +4,7 @@ import { type ImagePullSecretConfig, isVaultReference, parseVaultReference, + slugify, } from "@shared"; import { parseDockerArgsToLocalConfig } from "./docker-args-parser"; import type { McpCatalogFormValues } from "./mcp-catalog-form.types"; @@ -16,7 +17,7 @@ export function transformFormToApiData( values: McpCatalogFormValues, ): McpCatalogApiData { const data: McpCatalogApiData = { - slug: values.name, + slug: slugify(values.name), displayName: values.name, description: values.description || null, serverType: values.serverType, From b1da9bf845438ba8d353d55a6eb3511e1d174fbe Mon Sep 17 00:00:00 2001 From: brojd Date: Mon, 9 Mar 2026 22:26:21 +0100 Subject: [PATCH 3/5] use ensureUniqueSlug also on update --- .../src/models/internal-mcp-catalog.ts | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/platform/backend/src/models/internal-mcp-catalog.ts b/platform/backend/src/models/internal-mcp-catalog.ts index 1519b4bf49..65c2c0b4de 100644 --- a/platform/backend/src/models/internal-mcp-catalog.ts +++ b/platform/backend/src/models/internal-mcp-catalog.ts @@ -1,4 +1,4 @@ -import { and, desc, eq, ilike, inArray, or } from "drizzle-orm"; +import { and, desc, eq, ilike, inArray, ne, or } from "drizzle-orm"; import db, { schema } from "@/database"; import { secretManager } from "@/secrets-manager"; import type { @@ -268,6 +268,14 @@ class InternalMcpCatalogModel { ): Promise { const { labels, teams, ...dbValues } = catalogItem; + // Ensure slug is unique (excluding this item's own row) + if (dbValues.slug) { + dbValues.slug = await InternalMcpCatalogModel.ensureUniqueSlug( + dbValues.slug, + id, + ); + } + let dbItem: typeof schema.internalMcpCatalogTable.$inferSelect | undefined; if (Object.keys(dbValues).length > 0) { @@ -495,13 +503,22 @@ class InternalMcpCatalogModel { /** * Ensure slug is unique. If a catalog item with the same slug already exists, - * append a short random suffix (first 8 chars of a UUID). + * append a short random suffix (first 4 chars of a UUID). + * Pass excludeId to skip the item's own row when checking (used during updates). */ - private static async ensureUniqueSlug(slug: string): Promise { + private static async ensureUniqueSlug( + slug: string, + excludeId?: string, + ): Promise { + const conditions = [eq(schema.internalMcpCatalogTable.slug, slug)]; + if (excludeId) { + conditions.push(ne(schema.internalMcpCatalogTable.id, excludeId)); + } + const existing = await db .select({ id: schema.internalMcpCatalogTable.id }) .from(schema.internalMcpCatalogTable) - .where(eq(schema.internalMcpCatalogTable.slug, slug)) + .where(and(...conditions)) .limit(1); if (existing.length === 0) { From f590dcb93a0d5c0e59969e32832b1285c7ea05ec Mon Sep 17 00:00:00 2001 From: brojd Date: Mon, 9 Mar 2026 23:05:50 +0100 Subject: [PATCH 4/5] fix tests --- platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts | 9 ++++++--- platform/e2e-tests/utils.ts | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts b/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts index 8463b634ca..0c067965c1 100644 --- a/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts +++ b/platform/e2e-tests/tests/api/oauth-self-hosted.spec.ts @@ -211,7 +211,8 @@ test.describe("OAuth for Self-Hosted MCP Servers", () => { method: "post", urlSuffix: "/api/internal_mcp_catalog", data: { - name: `oauth-remote-test-${Date.now()}`, + slug: `oauth-remote-test-${Date.now()}`, + displayName: `oauth-remote-test-${Date.now()}`, description: "E2E test: remote server with OAuth", serverUrl: MCP_EXAMPLE_SERVER_MCP_URL, serverType: "remote", @@ -290,7 +291,8 @@ test.describe("OAuth for Self-Hosted MCP Servers", () => { method: "post", urlSuffix: "/api/internal_mcp_catalog", data: { - name: `oauth-local-http-test-${Date.now()}`, + slug: `oauth-local-http-test-${Date.now()}`, + displayName: `oauth-local-http-test-${Date.now()}`, description: "E2E test: self-hosted streamable-http server with OAuth", serverType: "local", authMethod: "oauth", @@ -352,7 +354,8 @@ test.describe("OAuth for Self-Hosted MCP Servers", () => { method: "post", urlSuffix: "/api/internal_mcp_catalog", data: { - name: `oauth-local-stdio-test-${Date.now()}`, + slug: `oauth-local-stdio-test-${Date.now()}`, + displayName: `oauth-local-stdio-test-${Date.now()}`, description: "E2E test: self-hosted stdio server with OAuth token via env var", serverType: "local", diff --git a/platform/e2e-tests/utils.ts b/platform/e2e-tests/utils.ts index 4d94b3d335..3625f1e646 100644 --- a/platform/e2e-tests/utils.ts +++ b/platform/e2e-tests/utils.ts @@ -689,7 +689,7 @@ export async function findCatalogItem( ); } - return catalog.find((item: { name: string }) => item.name === name); + return catalog.find((item: { slug: string }) => item.slug === name); } /** From f6032d9006501228ea083cdba459da1e840d12aa Mon Sep 17 00:00:00 2001 From: brojd Date: Mon, 9 Mar 2026 23:15:13 +0100 Subject: [PATCH 5/5] fix tests --- platform/backend/src/models/internal-mcp-catalog.test.ts | 2 +- platform/e2e-tests/utils.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/backend/src/models/internal-mcp-catalog.test.ts b/platform/backend/src/models/internal-mcp-catalog.test.ts index b7d9cb2538..5bba8fb104 100644 --- a/platform/backend/src/models/internal-mcp-catalog.test.ts +++ b/platform/backend/src/models/internal-mcp-catalog.test.ts @@ -610,7 +610,7 @@ describe("InternalMcpCatalogModel", () => { ); expect(archestraCatalog).toBeDefined(); - expect(archestraCatalog?.slug).toBe("archestra"); + expect(archestraCatalog?.slug).toBe("Archestra"); expect(archestraCatalog?.serverType).toBe("builtin"); }); }); diff --git a/platform/e2e-tests/utils.ts b/platform/e2e-tests/utils.ts index 3625f1e646..538882bcd4 100644 --- a/platform/e2e-tests/utils.ts +++ b/platform/e2e-tests/utils.ts @@ -5,7 +5,7 @@ import { type Locator, type Page, } from "@playwright/test"; -import { archestraApiSdk, DEFAULT_MCP_GATEWAY_NAME } from "@shared"; +import { archestraApiSdk, DEFAULT_MCP_GATEWAY_NAME, slugify } from "@shared"; import { testMcpServerCommand } from "@shared/test-mcp-server"; import { API_BASE_URL, @@ -122,13 +122,14 @@ export async function addCustomSelfHostedCatalogItem({ ); } + const slugifiedName = slugify(catalogItemName); const newCatalogItem = catalogItems.data.find( - (item) => item.slug === catalogItemName, + (item) => item.slug === slugifiedName, ); if (!newCatalogItem) { const itemNames = catalogItems.data.map((i) => i.slug).join(", "); throw new Error( - `Failed to find catalog item "${catalogItemName}". Available items: [${itemNames}]`, + `Failed to find catalog item "${catalogItemName}" (slugified: "${slugifiedName}"). Available items: [${itemNames}]`, ); } return { id: newCatalogItem.id, name: newCatalogItem.slug };