diff --git a/docs/generated/postgres-schema/README.md b/docs/generated/postgres-schema/README.md
index 2eec9e7a69f..bddc5934894 100644
--- a/docs/generated/postgres-schema/README.md
+++ b/docs/generated/postgres-schema/README.md
@@ -21,7 +21,7 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
| [public.agent_task_definition](public.agent_task_definition.md) | 7 | | BASE TABLE |
| [public.agent_task_run_lock](public.agent_task_run_lock.md) | 6 | | BASE TABLE |
| [public.agent_task_snapshot](public.agent_task_snapshot.md) | 8 | | BASE TABLE |
-| [public.agents](public.agents.md) | 11 | | BASE TABLE |
+| [public.agents](public.agents.md) | 12 | | BASE TABLE |
| [public.agents_memory_entries](public.agents_memory_entries.md) | 13 | | BASE TABLE |
| [public.agents_memory_entry_cursors](public.agents_memory_entry_cursors.md) | 6 | | BASE TABLE |
| [public.agents_memory_entry_locks](public.agents_memory_entry_locks.md) | 6 | | BASE TABLE |
@@ -489,6 +489,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_chat_subscriptions.md b/docs/generated/postgres-schema/public.agent_chat_subscriptions.md
index 6c3c0a8d4c5..ef34bc50478 100644
--- a/docs/generated/postgres-schema/public.agent_chat_subscriptions.md
+++ b/docs/generated/postgres-schema/public.agent_chat_subscriptions.md
@@ -48,6 +48,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_checkpoints.md b/docs/generated/postgres-schema/public.agent_checkpoints.md
index 01f507e0a23..2f84bd74092 100644
--- a/docs/generated/postgres-schema/public.agent_checkpoints.md
+++ b/docs/generated/postgres-schema/public.agent_checkpoints.md
@@ -46,6 +46,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_eval_dataset.md b/docs/generated/postgres-schema/public.agent_eval_dataset.md
index 7b19f5e9a26..95eb26e6cbb 100644
--- a/docs/generated/postgres-schema/public.agent_eval_dataset.md
+++ b/docs/generated/postgres-schema/public.agent_eval_dataset.md
@@ -61,6 +61,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_execution_threads.md b/docs/generated/postgres-schema/public.agent_execution_threads.md
index c578c613e17..a3d116befb7 100644
--- a/docs/generated/postgres-schema/public.agent_execution_threads.md
+++ b/docs/generated/postgres-schema/public.agent_execution_threads.md
@@ -82,6 +82,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_files.md b/docs/generated/postgres-schema/public.agent_files.md
index 12041cef160..c6610397810 100644
--- a/docs/generated/postgres-schema/public.agent_files.md
+++ b/docs/generated/postgres-schema/public.agent_files.md
@@ -56,6 +56,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_history.md b/docs/generated/postgres-schema/public.agent_history.md
index 378adb2e497..e50da32c98f 100644
--- a/docs/generated/postgres-schema/public.agent_history.md
+++ b/docs/generated/postgres-schema/public.agent_history.md
@@ -58,6 +58,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_task_definition.md b/docs/generated/postgres-schema/public.agent_task_definition.md
index cabbddd733b..37668892f62 100644
--- a/docs/generated/postgres-schema/public.agent_task_definition.md
+++ b/docs/generated/postgres-schema/public.agent_task_definition.md
@@ -51,6 +51,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agent_task_run_lock.md b/docs/generated/postgres-schema/public.agent_task_run_lock.md
index ab7c0613b04..9fe376312b1 100644
--- a/docs/generated/postgres-schema/public.agent_task_run_lock.md
+++ b/docs/generated/postgres-schema/public.agent_task_run_lock.md
@@ -47,6 +47,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents.md b/docs/generated/postgres-schema/public.agents.md
index 358b5a4b071..957edeb1c18 100644
--- a/docs/generated/postgres-schema/public.agents.md
+++ b/docs/generated/postgres-schema/public.agents.md
@@ -5,6 +5,7 @@
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| activeVersionId | varchar(36) | | true | | [public.agent_history](public.agent_history.md) | |
+| availableInMCP | boolean | false | false | | | Whether MCP clients granted agent scopes may operate on this agent |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| id | varchar(36) | | false | [public.agent_chat_subscriptions](public.agent_chat_subscriptions.md) [public.agent_checkpoints](public.agent_checkpoints.md) [public.agent_eval_dataset](public.agent_eval_dataset.md) [public.agent_execution_threads](public.agent_execution_threads.md) [public.agent_files](public.agent_files.md) [public.agent_history](public.agent_history.md) [public.agent_task_definition](public.agent_task_definition.md) [public.agent_task_run_lock](public.agent_task_run_lock.md) [public.agents_memory_entries](public.agents_memory_entries.md) [public.agents_memory_entry_cursors](public.agents_memory_entry_cursors.md) [public.agents_memory_entry_locks](public.agents_memory_entry_locks.md) [public.agents_memory_entry_sources](public.agents_memory_entry_sources.md) [public.agents_observation_cursors](public.agents_observation_cursors.md) [public.agents_observation_locks](public.agents_observation_locks.md) [public.agents_observations](public.agents_observations.md) | | |
| integrations | json | '[]'::json | false | | | |
@@ -23,6 +24,7 @@
| FK_940597dfe9753375309ce6aeea0 | FOREIGN KEY | FOREIGN KEY ("activeVersionId") REFERENCES agent_history("versionId") ON DELETE SET NULL |
| FK_a30d560207c4071d98aa03c179c | FOREIGN KEY | FOREIGN KEY ("projectId") REFERENCES project(id) ON DELETE CASCADE |
| PK_9c653f28ae19c5884d5baf6a1d9 | PRIMARY KEY | PRIMARY KEY (id) |
+| agents_availableInMCP_not_null | n | NOT NULL "availableInMCP" |
| agents_createdAt_not_null | n | NOT NULL "createdAt" |
| agents_id_not_null | n | NOT NULL id |
| agents_integrations_not_null | n | NOT NULL integrations |
@@ -65,6 +67,7 @@ erDiagram
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents_memory_entries.md b/docs/generated/postgres-schema/public.agents_memory_entries.md
index 6d4c06d0ff8..5d7ab6dba53 100644
--- a/docs/generated/postgres-schema/public.agents_memory_entries.md
+++ b/docs/generated/postgres-schema/public.agents_memory_entries.md
@@ -74,6 +74,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents_memory_entry_cursors.md b/docs/generated/postgres-schema/public.agents_memory_entry_cursors.md
index 66b4d7f2931..e1b7bd22256 100644
--- a/docs/generated/postgres-schema/public.agents_memory_entry_cursors.md
+++ b/docs/generated/postgres-schema/public.agents_memory_entry_cursors.md
@@ -50,6 +50,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents_memory_entry_locks.md b/docs/generated/postgres-schema/public.agents_memory_entry_locks.md
index 6d5d4bb9474..d32a0d664e2 100644
--- a/docs/generated/postgres-schema/public.agents_memory_entry_locks.md
+++ b/docs/generated/postgres-schema/public.agents_memory_entry_locks.md
@@ -50,6 +50,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents_memory_entry_sources.md b/docs/generated/postgres-schema/public.agents_memory_entry_sources.md
index addcc3b57af..dcfbb82d090 100644
--- a/docs/generated/postgres-schema/public.agents_memory_entry_sources.md
+++ b/docs/generated/postgres-schema/public.agents_memory_entry_sources.md
@@ -66,6 +66,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents_observation_cursors.md b/docs/generated/postgres-schema/public.agents_observation_cursors.md
index e61d9d3a3d6..59455a4bb85 100644
--- a/docs/generated/postgres-schema/public.agents_observation_cursors.md
+++ b/docs/generated/postgres-schema/public.agents_observation_cursors.md
@@ -50,6 +50,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents_observation_locks.md b/docs/generated/postgres-schema/public.agents_observation_locks.md
index f3e4842de58..3a6e176166d 100644
--- a/docs/generated/postgres-schema/public.agents_observation_locks.md
+++ b/docs/generated/postgres-schema/public.agents_observation_locks.md
@@ -54,6 +54,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.agents_observations.md b/docs/generated/postgres-schema/public.agents_observations.md
index 4d90eb39e64..22f37a6b446 100644
--- a/docs/generated/postgres-schema/public.agents_observations.md
+++ b/docs/generated/postgres-schema/public.agents_observations.md
@@ -73,6 +73,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/postgres-schema/public.project.md b/docs/generated/postgres-schema/public.project.md
index ba179000143..a626e6d4dfb 100644
--- a/docs/generated/postgres-schema/public.project.md
+++ b/docs/generated/postgres-schema/public.project.md
@@ -102,6 +102,7 @@ erDiagram
}
"public.agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
diff --git a/docs/generated/sqlite-schema/README.md b/docs/generated/sqlite-schema/README.md
index 0f5cae0de59..aad7d858f17 100644
--- a/docs/generated/sqlite-schema/README.md
+++ b/docs/generated/sqlite-schema/README.md
@@ -21,7 +21,7 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
| [agent_task_definition](agent_task_definition.md) | 7 | | table |
| [agent_task_run_lock](agent_task_run_lock.md) | 6 | | table |
| [agent_task_snapshot](agent_task_snapshot.md) | 8 | | table |
-| [agents](agents.md) | 11 | | table |
+| [agents](agents.md) | 12 | | table |
| [agents_memory_entries](agents_memory_entries.md) | 13 | | table |
| [agents_memory_entry_cursors](agents_memory_entry_cursors.md) | 6 | | table |
| [agents_memory_entry_locks](agents_memory_entry_locks.md) | 6 | | table |
@@ -155,8 +155,8 @@ erDiagram
"agent_task_definition" }o--|| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_task_run_lock" |o--|| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_task_snapshot" |o--|| "agent_history" : "FOREIGN KEY (versionId) REFERENCES agent_history (versionId) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
-"agents" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agents" }o--o| "agent_history" : "FOREIGN KEY (activeVersionId) REFERENCES agent_history (versionId) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
+"agents" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agents_memory_entries" }o--o| "agents_memory_entries" : "FOREIGN KEY (supersededBy) REFERENCES agents_memory_entries (id) ON UPDATE NO ACTION ON DELETE NO ACTION MATCH NONE"
"agents_memory_entries" }o--|| "agents_resources" : "FOREIGN KEY (resourceId) REFERENCES agents_resources (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agents_memory_entries" }o--|| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
@@ -476,6 +476,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_chat_subscriptions.md b/docs/generated/sqlite-schema/agent_chat_subscriptions.md
index dbf2f877efa..714f4582614 100644
--- a/docs/generated/sqlite-schema/agent_chat_subscriptions.md
+++ b/docs/generated/sqlite-schema/agent_chat_subscriptions.md
@@ -57,6 +57,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_checkpoints.md b/docs/generated/sqlite-schema/agent_checkpoints.md
index ed04354728a..fa22cf4b59b 100644
--- a/docs/generated/sqlite-schema/agent_checkpoints.md
+++ b/docs/generated/sqlite-schema/agent_checkpoints.md
@@ -54,6 +54,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_eval_dataset.md b/docs/generated/sqlite-schema/agent_eval_dataset.md
index 3fb21fe79f8..eadd1193682 100644
--- a/docs/generated/sqlite-schema/agent_eval_dataset.md
+++ b/docs/generated/sqlite-schema/agent_eval_dataset.md
@@ -66,6 +66,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_execution_threads.md b/docs/generated/sqlite-schema/agent_execution_threads.md
index 17c617dc5ef..587378ed8f5 100644
--- a/docs/generated/sqlite-schema/agent_execution_threads.md
+++ b/docs/generated/sqlite-schema/agent_execution_threads.md
@@ -83,6 +83,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_files.md b/docs/generated/sqlite-schema/agent_files.md
index 43dd427be19..cb67a888cec 100644
--- a/docs/generated/sqlite-schema/agent_files.md
+++ b/docs/generated/sqlite-schema/agent_files.md
@@ -60,6 +60,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_history.md b/docs/generated/sqlite-schema/agent_history.md
index 1d572325a53..3679e183648 100644
--- a/docs/generated/sqlite-schema/agent_history.md
+++ b/docs/generated/sqlite-schema/agent_history.md
@@ -65,6 +65,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_task_definition.md b/docs/generated/sqlite-schema/agent_task_definition.md
index ded38141a54..6d4c5e2bee2 100644
--- a/docs/generated/sqlite-schema/agent_task_definition.md
+++ b/docs/generated/sqlite-schema/agent_task_definition.md
@@ -56,6 +56,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agent_task_run_lock.md b/docs/generated/sqlite-schema/agent_task_run_lock.md
index 5c8184066e8..8fcaa3ce749 100644
--- a/docs/generated/sqlite-schema/agent_task_run_lock.md
+++ b/docs/generated/sqlite-schema/agent_task_run_lock.md
@@ -54,6 +54,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents.md b/docs/generated/sqlite-schema/agents.md
index d925895eee7..338cdea363e 100644
--- a/docs/generated/sqlite-schema/agents.md
+++ b/docs/generated/sqlite-schema/agents.md
@@ -6,7 +6,7 @@
Table Definition
```sql
-CREATE TABLE "agents" ("id" varchar(36) PRIMARY KEY NOT NULL, "name" varchar(128) NOT NULL, "projectId" varchar(255) NOT NULL, "integrations" text NOT NULL DEFAULT ('[]'), "schema" text, "tools" text NOT NULL DEFAULT ('{}'), "skills" text NOT NULL DEFAULT ('{}'), "versionId" varchar(36), "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "activeVersionId" varchar(36), CONSTRAINT "FK_940597dfe9753375309ce6aeea0" FOREIGN KEY ("activeVersionId") REFERENCES "agent_history" ("versionId") ON DELETE SET NULL ON UPDATE NO ACTION, CONSTRAINT "FK_a30d560207c4071d98aa03c179c" FOREIGN KEY ("projectId") REFERENCES "project" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)
+CREATE TABLE "agents" ("id" varchar(36) PRIMARY KEY NOT NULL, "name" varchar(128) NOT NULL, "projectId" varchar(255) NOT NULL, "integrations" text NOT NULL DEFAULT ('[]'), "schema" text, "tools" text NOT NULL DEFAULT ('{}'), "skills" text NOT NULL DEFAULT ('{}'), "versionId" varchar(36), "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "activeVersionId" varchar(36), "availableInMCP" boolean NOT NULL DEFAULT (false), CONSTRAINT "FK_a30d560207c4071d98aa03c179c" FOREIGN KEY ("projectId") REFERENCES "project" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_940597dfe9753375309ce6aeea0" FOREIGN KEY ("activeVersionId") REFERENCES "agent_history" ("versionId") ON DELETE SET NULL ON UPDATE NO ACTION)
```
@@ -16,6 +16,7 @@ CREATE TABLE "agents" ("id" varchar(36) PRIMARY KEY NOT NULL, "name" varchar(128
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| activeVersionId | varchar(36) | | true | | [agent_history](agent_history.md) | |
+| availableInMCP | boolean | false | false | | | |
| createdAt | datetime(3) | STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') | false | | | |
| id | varchar(36) | | false | [agent_chat_subscriptions](agent_chat_subscriptions.md) [agent_checkpoints](agent_checkpoints.md) [agent_eval_dataset](agent_eval_dataset.md) [agent_execution_threads](agent_execution_threads.md) [agent_files](agent_files.md) [agent_history](agent_history.md) [agent_task_definition](agent_task_definition.md) [agent_task_run_lock](agent_task_run_lock.md) [agents_memory_entries](agents_memory_entries.md) [agents_memory_entry_cursors](agents_memory_entry_cursors.md) [agents_memory_entry_locks](agents_memory_entry_locks.md) [agents_memory_entry_sources](agents_memory_entry_sources.md) [agents_observation_cursors](agents_observation_cursors.md) [agents_observation_locks](agents_observation_locks.md) [agents_observations](agents_observations.md) | | |
| integrations | TEXT | '[]' | false | | | |
@@ -31,8 +32,8 @@ CREATE TABLE "agents" ("id" varchar(36) PRIMARY KEY NOT NULL, "name" varchar(128
| Name | Type | Definition |
| ---- | ---- | ---------- |
-| - (Foreign key ID: 0) | FOREIGN KEY | FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE |
-| - (Foreign key ID: 1) | FOREIGN KEY | FOREIGN KEY (activeVersionId) REFERENCES agent_history (versionId) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE |
+| - (Foreign key ID: 0) | FOREIGN KEY | FOREIGN KEY (activeVersionId) REFERENCES agent_history (versionId) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE |
+| - (Foreign key ID: 1) | FOREIGN KEY | FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE |
| id | PRIMARY KEY | PRIMARY KEY (id) |
| sqlite_autoindex_agents_1 | PRIMARY KEY | PRIMARY KEY (id) |
@@ -69,6 +70,7 @@ erDiagram
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents_memory_entries.md b/docs/generated/sqlite-schema/agents_memory_entries.md
index 2601608f3d9..8f78854a99e 100644
--- a/docs/generated/sqlite-schema/agents_memory_entries.md
+++ b/docs/generated/sqlite-schema/agents_memory_entries.md
@@ -77,6 +77,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents_memory_entry_cursors.md b/docs/generated/sqlite-schema/agents_memory_entry_cursors.md
index 8d8bdf303b0..064f6523987 100644
--- a/docs/generated/sqlite-schema/agents_memory_entry_cursors.md
+++ b/docs/generated/sqlite-schema/agents_memory_entry_cursors.md
@@ -57,6 +57,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents_memory_entry_locks.md b/docs/generated/sqlite-schema/agents_memory_entry_locks.md
index 56144bdceba..f2a40760528 100644
--- a/docs/generated/sqlite-schema/agents_memory_entry_locks.md
+++ b/docs/generated/sqlite-schema/agents_memory_entry_locks.md
@@ -57,6 +57,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents_memory_entry_sources.md b/docs/generated/sqlite-schema/agents_memory_entry_sources.md
index 357d217c916..4bb82b6664b 100644
--- a/docs/generated/sqlite-schema/agents_memory_entry_sources.md
+++ b/docs/generated/sqlite-schema/agents_memory_entry_sources.md
@@ -69,6 +69,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents_observation_cursors.md b/docs/generated/sqlite-schema/agents_observation_cursors.md
index 484e0a78f5b..0b238c3fd21 100644
--- a/docs/generated/sqlite-schema/agents_observation_cursors.md
+++ b/docs/generated/sqlite-schema/agents_observation_cursors.md
@@ -57,6 +57,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents_observation_locks.md b/docs/generated/sqlite-schema/agents_observation_locks.md
index f755493c2a9..995c689be1a 100644
--- a/docs/generated/sqlite-schema/agents_observation_locks.md
+++ b/docs/generated/sqlite-schema/agents_observation_locks.md
@@ -61,6 +61,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/agents_observations.md b/docs/generated/sqlite-schema/agents_observations.md
index aaa26b0dbdd..cafb9cb0216 100644
--- a/docs/generated/sqlite-schema/agents_observations.md
+++ b/docs/generated/sqlite-schema/agents_observations.md
@@ -76,6 +76,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/docs/generated/sqlite-schema/project.md b/docs/generated/sqlite-schema/project.md
index 9b2d929dec3..0e7ace1f8fb 100644
--- a/docs/generated/sqlite-schema/project.md
+++ b/docs/generated/sqlite-schema/project.md
@@ -108,6 +108,7 @@ erDiagram
}
"agents" {
varchar_36_ activeVersionId FK
+ boolean availableInMCP
datetime_3_ createdAt
varchar_36_ id PK
TEXT integrations
diff --git a/packages/@n8n/db/src/migrations/common/1784897791636-AddAvailableInMcpToAgents.ts b/packages/@n8n/db/src/migrations/common/1784897791636-AddAvailableInMcpToAgents.ts
new file mode 100644
index 00000000000..a1e6c961a59
--- /dev/null
+++ b/packages/@n8n/db/src/migrations/common/1784897791636-AddAvailableInMcpToAgents.ts
@@ -0,0 +1,19 @@
+import type { MigrationContext, ReversibleMigration } from '../migration-types';
+
+export class AddAvailableInMcpToAgents1784897791636 implements ReversibleMigration {
+ async up({ schemaBuilder: { addColumns, column } }: MigrationContext) {
+ await addColumns(
+ 'agents',
+ [
+ column('availableInMCP')
+ .bool.notNull.default(false)
+ .comment('Whether MCP clients granted agent scopes may operate on this agent'),
+ ],
+ { recreatesOnSqlite: true },
+ );
+ }
+
+ async down({ schemaBuilder: { dropColumns } }: MigrationContext) {
+ await dropColumns('agents', ['availableInMCP'], { recreatesOnSqlite: true });
+ }
+}
diff --git a/packages/@n8n/db/src/migrations/postgresdb/index.ts b/packages/@n8n/db/src/migrations/postgresdb/index.ts
index fcdd15e889a..70ea9605657 100644
--- a/packages/@n8n/db/src/migrations/postgresdb/index.ts
+++ b/packages/@n8n/db/src/migrations/postgresdb/index.ts
@@ -229,6 +229,7 @@ import { CreateWorkflowReviewRequestTables1784000000052 } from '../common/178400
import { AddStoredAtToAgentExecution1784815940110 } from '../common/1784815940110-AddStoredAtToAgentExecution';
import { AddInstanceCredentials1784815940111 } from '../common/1784815940111-AddInstanceCredentials';
import { CreateAgentEvalTables1784815940112 } from '../common/1784815940112-CreateAgentEvalTables';
+import { AddAvailableInMcpToAgents1784897791636 } from '../common/1784897791636-AddAvailableInMcpToAgents';
import type { Migration } from '../migration-types';
export const postgresMigrations: Migration[] = [
@@ -463,4 +464,5 @@ export const postgresMigrations: Migration[] = [
AddStoredAtToAgentExecution1784815940110,
AddInstanceCredentials1784815940111,
CreateAgentEvalTables1784815940112,
+ AddAvailableInMcpToAgents1784897791636,
];
diff --git a/packages/@n8n/db/src/migrations/sqlite/1784897791636-AddAvailableInMcpToAgents.ts b/packages/@n8n/db/src/migrations/sqlite/1784897791636-AddAvailableInMcpToAgents.ts
new file mode 100644
index 00000000000..ba82fe6f29f
--- /dev/null
+++ b/packages/@n8n/db/src/migrations/sqlite/1784897791636-AddAvailableInMcpToAgents.ts
@@ -0,0 +1,9 @@
+import { AddAvailableInMcpToAgents1784897791636 as BaseMigration } from '../common/1784897791636-AddAvailableInMcpToAgents';
+
+/**
+ * Adding a column recreates `agents` on SQLite, and several agent tables have
+ * CASCADE FKs to it. Disable FKs for the migration's duration.
+ */
+export class AddAvailableInMcpToAgents1784897791636 extends BaseMigration {
+ withFKsDisabled = true as const;
+}
diff --git a/packages/@n8n/db/src/migrations/sqlite/index.ts b/packages/@n8n/db/src/migrations/sqlite/index.ts
index 3679349e891..f95c4afed2d 100644
--- a/packages/@n8n/db/src/migrations/sqlite/index.ts
+++ b/packages/@n8n/db/src/migrations/sqlite/index.ts
@@ -58,6 +58,7 @@ import { AddProjectIdToInstanceAiThread1784000000028 } from './1784000000028-Add
import { AllowAzureStoredAt1784000000034 } from './1784000000034-AllowAzureStoredAt';
import { DropAgentDescriptionFromAgents1784000000037 } from './1784000000037-DropAgentDescriptionFromAgents';
import { AddRecurringCronScheduleKind1784000000045 } from './1784000000045-AddRecurringCronScheduleKind';
+import { AddAvailableInMcpToAgents1784897791636 } from './1784897791636-AddAvailableInMcpToAgents';
import { UniqueWorkflowNames1620821879465 } from '../common/1620821879465-UniqueWorkflowNames';
import { UpdateWorkflowCredentials1630330987096 } from '../common/1630330987096-UpdateWorkflowCredentials';
import { AddNodeIds1658930531669 } from '../common/1658930531669-AddNodeIds';
@@ -445,6 +446,7 @@ const sqliteMigrations: Migration[] = [
AddStoredAtToAgentExecution1784815940110,
AddInstanceCredentials1784815940111,
CreateAgentEvalTables1784815940112,
+ AddAvailableInMcpToAgents1784897791636,
];
export { sqliteMigrations };
diff --git a/packages/cli/test/migration/1784897791636-add-available-in-mcp-to-agents.test.ts b/packages/cli/test/migration/1784897791636-add-available-in-mcp-to-agents.test.ts
new file mode 100644
index 00000000000..57a085542a7
--- /dev/null
+++ b/packages/cli/test/migration/1784897791636-add-available-in-mcp-to-agents.test.ts
@@ -0,0 +1,235 @@
+import {
+ createTestMigrationContext,
+ initDbUpToMigration,
+ runSingleMigration,
+ undoLastSingleMigration,
+ type TestMigrationContext,
+} from '@n8n/backend-test-utils';
+import { DbConnection } from '@n8n/db';
+import { Container } from '@n8n/di';
+import { DataSource } from '@n8n/typeorm';
+import { randomUUID } from 'node:crypto';
+
+const MIGRATION_NAME = 'AddAvailableInMcpToAgents1784897791636';
+
+describe('AddAvailableInMcpToAgents Migration', () => {
+ let dataSource: DataSource;
+
+ async function withContext(fn: (context: TestMigrationContext) => Promise): Promise {
+ const context = createTestMigrationContext(dataSource);
+ try {
+ return await fn(context);
+ } finally {
+ await context.queryRunner.release();
+ }
+ }
+
+ beforeAll(async () => {
+ const dbConnection = Container.get(DbConnection);
+ await dbConnection.init();
+ dataSource = Container.get(DataSource);
+ });
+
+ beforeEach(async () => {
+ await withContext(async (context) => {
+ await context.queryRunner.clearDatabase();
+ });
+ await initDbUpToMigration(MIGRATION_NAME);
+ });
+
+ afterAll(async () => {
+ const dbConnection = Container.get(DbConnection);
+ await dbConnection.close();
+ });
+
+ async function insertProject(context: TestMigrationContext, id: string): Promise {
+ const tableName = context.escape.tableName('project');
+ await context.runQuery(
+ `INSERT INTO ${tableName} ("id", "name", "type", "createdAt", "updatedAt")
+ VALUES (:id, :name, :type, :createdAt, :updatedAt)`,
+ {
+ id,
+ name: `project-${id.slice(0, 8)}`,
+ type: 'personal',
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ },
+ );
+ }
+
+ async function insertAgent(
+ context: TestMigrationContext,
+ data: { id: string; projectId: string },
+ ): Promise {
+ const tableName = context.escape.tableName('agents');
+ await context.runQuery(
+ `INSERT INTO ${tableName}
+ ("id", "name", "projectId", "integrations", "tools", "skills", "createdAt", "updatedAt")
+ VALUES (:id, :name, :projectId, :integrations, :tools, :skills, :createdAt, :updatedAt)`,
+ {
+ id: data.id,
+ name: `agent-${data.id.slice(0, 8)}`,
+ projectId: data.projectId,
+ integrations: '[]',
+ tools: '{}',
+ skills: '{}',
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ },
+ );
+ }
+
+ async function insertAgentHistory(
+ context: TestMigrationContext,
+ data: { versionId: string; agentId: string },
+ ): Promise {
+ const tableName = context.escape.tableName('agent_history');
+ await context.runQuery(
+ `INSERT INTO ${tableName} ("versionId", "agentId", "author", "createdAt", "updatedAt")
+ VALUES (:versionId, :agentId, :author, :createdAt, :updatedAt)`,
+ {
+ versionId: data.versionId,
+ agentId: data.agentId,
+ author: 'Test User',
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ },
+ );
+ }
+
+ async function getColumnMeta(context: TestMigrationContext, columnName: string) {
+ if (context.isSqlite) {
+ const rows: Array<{ name: string; notnull: number; dflt_value: string | null }> =
+ await context.queryRunner.query(`PRAGMA table_info(${context.escape.tableName('agents')})`);
+ return rows.find((r) => r.name === columnName);
+ }
+ const rows: Array<{
+ column_name: string;
+ is_nullable: string;
+ column_default: string | null;
+ }> = await context.queryRunner.query(
+ 'SELECT column_name, is_nullable, column_default FROM information_schema.columns WHERE table_name = $1 AND column_name = $2',
+ [`${context.tablePrefix}agents`, columnName],
+ );
+ return rows[0];
+ }
+
+ describe('up', () => {
+ it('should add availableInMCP as NOT NULL with default false', async () => {
+ await runSingleMigration(MIGRATION_NAME);
+ dataSource = Container.get(DataSource);
+
+ await withContext(async (context) => {
+ const col = await getColumnMeta(context, 'availableInMCP');
+ expect(col).toBeDefined();
+ if (context.isSqlite) {
+ expect((col as { notnull: number }).notnull).toBe(1);
+ } else {
+ expect((col as { is_nullable: string }).is_nullable).toBe('NO');
+ }
+ });
+ });
+
+ it('should backfill false on existing agents', async () => {
+ const projectId = randomUUID();
+ const agentId = randomUUID();
+
+ await withContext(async (context) => {
+ await insertProject(context, projectId);
+ await insertAgent(context, { id: agentId, projectId });
+ });
+
+ await runSingleMigration(MIGRATION_NAME);
+ dataSource = Container.get(DataSource);
+
+ await withContext(async (context) => {
+ const rows = await context.runQuery>(
+ `SELECT "availableInMCP" FROM ${context.escape.tableName('agents')} WHERE "id" = :id`,
+ { id: agentId },
+ );
+ expect(rows).toHaveLength(1);
+ expect(Boolean(rows[0].availableInMCP)).toBe(false);
+ });
+ });
+
+ it('should default availableInMCP to false on inserts that omit it', async () => {
+ await runSingleMigration(MIGRATION_NAME);
+ dataSource = Container.get(DataSource);
+
+ const projectId = randomUUID();
+ const agentId = randomUUID();
+
+ await withContext(async (context) => {
+ await insertProject(context, projectId);
+ await insertAgent(context, { id: agentId, projectId });
+
+ const rows = await context.runQuery>(
+ `SELECT "availableInMCP" FROM ${context.escape.tableName('agents')} WHERE "id" = :id`,
+ { id: agentId },
+ );
+ expect(Boolean(rows[0].availableInMCP)).toBe(false);
+ });
+ });
+
+ it('should preserve rows in tables with CASCADE FKs to agents', async () => {
+ // On SQLite the migration recreates `agents` (drop + rename), which
+ // would cascade-delete child rows unless FKs are disabled for the
+ // migration's duration (withFKsDisabled on the sqlite subclass).
+ const projectId = randomUUID();
+ const agentId = randomUUID();
+ const versionId = randomUUID();
+
+ await withContext(async (context) => {
+ await insertProject(context, projectId);
+ await insertAgent(context, { id: agentId, projectId });
+ await insertAgentHistory(context, { versionId, agentId });
+ });
+
+ await runSingleMigration(MIGRATION_NAME);
+ dataSource = Container.get(DataSource);
+
+ await withContext(async (context) => {
+ const agentRows = await context.runQuery>(
+ `SELECT "id" FROM ${context.escape.tableName('agents')} WHERE "id" = :id`,
+ { id: agentId },
+ );
+ expect(agentRows).toHaveLength(1);
+
+ const historyRows = await context.runQuery>(
+ `SELECT "versionId" FROM ${context.escape.tableName('agent_history')} WHERE "agentId" = :id`,
+ { id: agentId },
+ );
+ expect(historyRows).toHaveLength(1);
+ expect(historyRows[0].versionId).toBe(versionId);
+ });
+ });
+ });
+
+ describe('down', () => {
+ it('should remove the column and preserve child rows', async () => {
+ const projectId = randomUUID();
+ const agentId = randomUUID();
+ const versionId = randomUUID();
+
+ await withContext(async (context) => {
+ await insertProject(context, projectId);
+ await insertAgent(context, { id: agentId, projectId });
+ await insertAgentHistory(context, { versionId, agentId });
+ });
+
+ await runSingleMigration(MIGRATION_NAME);
+ await undoLastSingleMigration();
+ dataSource = Container.get(DataSource);
+
+ await withContext(async (context) => {
+ expect(await getColumnMeta(context, 'availableInMCP')).toBeUndefined();
+
+ const historyRows = await context.runQuery>(
+ `SELECT "versionId" FROM ${context.escape.tableName('agent_history')} WHERE "agentId" = :id`,
+ { id: agentId },
+ );
+ expect(historyRows).toHaveLength(1);
+ });
+ });
+ });
+});