Skip to content

Commit f36af63

Browse files
authored
Standardize Active-State Field for prompts/resources/virtual server & Add UUID Support for Prompts & Resources (#1543)
* UUID res and prompt Signed-off-by: rakdutta <[email protected]> * get_prompt main Signed-off-by: rakdutta <[email protected]> * flake8 Signed-off-by: rakdutta <[email protected]> * UUID doctest Signed-off-by: rakdutta <[email protected]> * UUID pytest fix Signed-off-by: rakdutta <[email protected]> * uuid alembic Signed-off-by: rakdutta <[email protected]> * alembic Signed-off-by: rakdutta <[email protected]> * alembic prompts and resources Signed-off-by: rakdutta <[email protected]> * alembic Signed-off-by: rakdutta <[email protected]> * js Signed-off-by: rakdutta <[email protected]> * enabled Signed-off-by: rakdutta <[email protected]> * enable prompts Signed-off-by: rakdutta <[email protected]> * enabled Signed-off-by: rakdutta <[email protected]> * resource enabled Signed-off-by: rakdutta <[email protected]> * change Signed-off-by: rakdutta <[email protected]> * list server res Signed-off-by: rakdutta <[email protected]> * doctest Signed-off-by: rakdutta <[email protected]> * alembic Signed-off-by: rakdutta <[email protected]> * pytest Signed-off-by: rakdutta <[email protected]> * pytest Signed-off-by: rakdutta <[email protected]> * conflict resolve Signed-off-by: rakdutta <[email protected]> * isort Signed-off-by: rakdutta <[email protected]> * pytest Signed-off-by: rakdutta <[email protected]> --------- Signed-off-by: rakdutta <[email protected]>
1 parent 9a6c3bc commit f36af63

26 files changed

+1072
-315
lines changed

mcpgateway/admin.py

Lines changed: 41 additions & 44 deletions
Large diffs are not rendered by default.

mcpgateway/alembic/versions/356a2d4eed6f_uuid_change_for_prompt_and_resources.py

Lines changed: 770 additions & 0 deletions
Large diffs are not rendered by default.

mcpgateway/db.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,15 +1428,15 @@ def reject(self, admin_email: str, reason: str, notes: Optional[str] = None) ->
14281428
"server_resource_association",
14291429
Base.metadata,
14301430
Column("server_id", String(36), ForeignKey("servers.id"), primary_key=True),
1431-
Column("resource_id", Integer, ForeignKey("resources.id"), primary_key=True),
1431+
Column("resource_id", String(36), ForeignKey("resources.id"), primary_key=True),
14321432
)
14331433

14341434
# Association table for servers and prompts
14351435
server_prompt_association = Table(
14361436
"server_prompt_association",
14371437
Base.metadata,
14381438
Column("server_id", String(36), ForeignKey("servers.id"), primary_key=True),
1439-
Column("prompt_id", Integer, ForeignKey("prompts.id"), primary_key=True),
1439+
Column("prompt_id", String(36), ForeignKey("prompts.id"), primary_key=True),
14401440
)
14411441

14421442
# Association table for servers and A2A agents
@@ -1496,7 +1496,7 @@ class ResourceMetric(Base):
14961496
14971497
Attributes:
14981498
id (int): Primary key.
1499-
resource_id (int): Foreign key linking to the resource.
1499+
resource_id (str): Foreign key linking to the resource.
15001500
timestamp (datetime): The time when the invocation occurred.
15011501
response_time (float): The response time in seconds.
15021502
is_success (bool): True if the invocation succeeded, False otherwise.
@@ -1506,7 +1506,7 @@ class ResourceMetric(Base):
15061506
__tablename__ = "resource_metrics"
15071507

15081508
id: Mapped[int] = mapped_column(primary_key=True)
1509-
resource_id: Mapped[int] = mapped_column(Integer, ForeignKey("resources.id"), nullable=False)
1509+
resource_id: Mapped[str] = mapped_column(String(36), ForeignKey("resources.id"), nullable=False)
15101510
timestamp: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
15111511
response_time: Mapped[float] = mapped_column(Float, nullable=False)
15121512
is_success: Mapped[bool] = mapped_column(Boolean, nullable=False)
@@ -1548,7 +1548,7 @@ class PromptMetric(Base):
15481548
15491549
Attributes:
15501550
id (int): Primary key.
1551-
prompt_id (int): Foreign key linking to the prompt.
1551+
prompt_id (str): Foreign key linking to the prompt.
15521552
timestamp (datetime): The time when the invocation occurred.
15531553
response_time (float): The response time in seconds.
15541554
is_success (bool): True if the invocation succeeded, False otherwise.
@@ -1558,7 +1558,7 @@ class PromptMetric(Base):
15581558
__tablename__ = "prompt_metrics"
15591559

15601560
id: Mapped[int] = mapped_column(primary_key=True)
1561-
prompt_id: Mapped[int] = mapped_column(Integer, ForeignKey("prompts.id"), nullable=False)
1561+
prompt_id: Mapped[str] = mapped_column(String(36), ForeignKey("prompts.id"), nullable=False)
15621562
timestamp: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
15631563
response_time: Mapped[float] = mapped_column(Float, nullable=False)
15641564
is_success: Mapped[bool] = mapped_column(Boolean, nullable=False)
@@ -2210,7 +2210,7 @@ class Resource(Base):
22102210

22112211
__tablename__ = "resources"
22122212

2213-
id: Mapped[int] = mapped_column(primary_key=True)
2213+
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: uuid.uuid4().hex)
22142214
uri: Mapped[str] = mapped_column(String(767), nullable=False)
22152215
name: Mapped[str] = mapped_column(String(255), nullable=False)
22162216
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
@@ -2219,7 +2219,8 @@ class Resource(Base):
22192219
uri_template: Mapped[Optional[str]] = mapped_column(Text, nullable=True) # URI template for parameterized resources
22202220
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
22212221
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
2222-
is_active: Mapped[bool] = mapped_column(default=True)
2222+
# is_active: Mapped[bool] = mapped_column(default=True)
2223+
enabled: Mapped[bool] = mapped_column(default=True)
22232224
tags: Mapped[List[str]] = mapped_column(JSON, default=list, nullable=False)
22242225

22252226
# Comprehensive metadata for audit tracking
@@ -2423,7 +2424,7 @@ class ResourceSubscription(Base):
24232424
__tablename__ = "resource_subscriptions"
24242425

24252426
id: Mapped[int] = mapped_column(primary_key=True)
2426-
resource_id: Mapped[int] = mapped_column(ForeignKey("resources.id"))
2427+
resource_id: Mapped[str] = mapped_column(ForeignKey("resources.id"))
24272428
subscriber_id: Mapped[str] = mapped_column(String(255), nullable=False) # Client identifier
24282429
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
24292430
last_notification: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
@@ -2469,14 +2470,15 @@ class Prompt(Base):
24692470

24702471
__tablename__ = "prompts"
24712472

2472-
id: Mapped[int] = mapped_column(primary_key=True)
2473+
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: uuid.uuid4().hex)
24732474
name: Mapped[str] = mapped_column(String(255), nullable=False)
24742475
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
24752476
template: Mapped[str] = mapped_column(Text)
24762477
argument_schema: Mapped[Dict[str, Any]] = mapped_column(JSON)
24772478
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
24782479
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
2479-
is_active: Mapped[bool] = mapped_column(default=True)
2480+
# is_active: Mapped[bool] = mapped_column(default=True)
2481+
enabled: Mapped[bool] = mapped_column(default=True)
24802482
tags: Mapped[List[str]] = mapped_column(JSON, default=list, nullable=False)
24812483

24822484
# Comprehensive metadata for audit tracking
@@ -2667,7 +2669,8 @@ class Server(Base):
26672669
icon: Mapped[Optional[str]] = mapped_column(String(767), nullable=True)
26682670
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
26692671
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
2670-
is_active: Mapped[bool] = mapped_column(default=True)
2672+
# is_active: Mapped[bool] = mapped_column(default=True)
2673+
enabled: Mapped[bool] = mapped_column(default=True)
26712674
tags: Mapped[List[str]] = mapped_column(JSON, default=list, nullable=False)
26722675

26732676
# Comprehensive metadata for audit tracking

mcpgateway/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,7 +2758,7 @@ async def list_resource_templates(
27582758
Returns:
27592759
ListResourceTemplatesResult: A paginated list of resource templates.
27602760
"""
2761-
logger.debug(f"User {user} requested resource templates")
2761+
logger.info(f"User {user} requested resource templates")
27622762
resource_templates = await resource_service.list_resource_templates(db)
27632763
# For simplicity, we're not implementing real pagination here
27642764
return ListResourceTemplatesResult(_meta={}, resource_templates=resource_templates, next_cursor=None) # No pagination for now
@@ -2767,7 +2767,7 @@ async def list_resource_templates(
27672767
@resource_router.post("/{resource_id}/toggle")
27682768
@require_permission("resources.update")
27692769
async def toggle_resource_status(
2770-
resource_id: int,
2770+
resource_id: str,
27712771
activate: bool = True,
27722772
db: Session = Depends(get_db),
27732773
user=Depends(get_current_user_with_permissions),
@@ -2776,7 +2776,7 @@ async def toggle_resource_status(
27762776
Activate or deactivate a resource by its ID.
27772777
27782778
Args:
2779-
resource_id (int): The ID of the resource.
2779+
resource_id (str): The ID of the resource.
27802780
activate (bool): True to activate, False to deactivate.
27812781
db (Session): Database session.
27822782
user (str): Authenticated user.
@@ -3126,7 +3126,7 @@ async def subscribe_resource(user=Depends(get_current_user_with_permissions)) ->
31263126
@prompt_router.post("/{prompt_id}/toggle")
31273127
@require_permission("prompts.update")
31283128
async def toggle_prompt_status(
3129-
prompt_id: int,
3129+
prompt_id: str,
31303130
activate: bool = True,
31313131
db: Session = Depends(get_db),
31323132
user=Depends(get_current_user_with_permissions),

mcpgateway/schemas.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,7 +1771,7 @@ class ResourceRead(BaseModelWithConfigDict):
17711771
- Metrics: Aggregated metrics for the resource invocations.
17721772
"""
17731773

1774-
id: int
1774+
id: str = Field(description="Unique ID of the resource")
17751775
uri: str
17761776
name: str
17771777
description: Optional[str]
@@ -1780,7 +1780,7 @@ class ResourceRead(BaseModelWithConfigDict):
17801780
size: Optional[int]
17811781
created_at: datetime
17821782
updated_at: datetime
1783-
is_active: bool
1783+
enabled: bool
17841784
metrics: ResourceMetrics
17851785
tags: List[Dict[str, str]] = Field(default_factory=list, description="Tags for categorizing the resource")
17861786

@@ -2280,14 +2280,15 @@ class PromptRead(BaseModelWithConfigDict):
22802280
- Metrics: Aggregated metrics for the prompt invocations.
22812281
"""
22822282

2283-
id: int
2283+
id: str = Field(description="Unique ID of the prompt")
22842284
name: str
22852285
description: Optional[str]
22862286
template: str
22872287
arguments: List[PromptArgument]
22882288
created_at: datetime
22892289
updated_at: datetime
2290-
is_active: bool
2290+
# is_active: bool
2291+
enabled: bool
22912292
tags: List[Dict[str, str]] = Field(default_factory=list, description="Tags for categorizing the prompt")
22922293
metrics: PromptMetrics
22932294

@@ -3710,10 +3711,11 @@ class ServerRead(BaseModelWithConfigDict):
37103711
icon: Optional[str]
37113712
created_at: datetime
37123713
updated_at: datetime
3713-
is_active: bool
3714+
# is_active: bool
3715+
enabled: bool
37143716
associated_tools: List[str] = []
3715-
associated_resources: List[int] = []
3716-
associated_prompts: List[int] = []
3717+
associated_resources: List[str] = []
3718+
associated_prompts: List[str] = []
37173719
associated_a2a_agents: List[str] = []
37183720
metrics: ServerMetrics
37193721
tags: List[Dict[str, str]] = Field(default_factory=list, description="Tags for categorizing the server")

mcpgateway/services/completion_service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ async def _complete_prompt_argument(self, db: Session, ref: Dict[str, Any], arg_
176176
if not prompt_name:
177177
raise CompletionError("Missing prompt name")
178178

179-
prompt = db.execute(select(DbPrompt).where(DbPrompt.name == prompt_name).where(DbPrompt.is_active)).scalar_one_or_none()
179+
# Only consider prompts that are enabled (renamed from `is_active` -> `enabled`)
180+
prompt = db.execute(select(DbPrompt).where(DbPrompt.name == prompt_name).where(DbPrompt.enabled)).scalar_one_or_none()
180181

181182
if not prompt:
182183
raise CompletionError(f"Prompt not found: {prompt_name}")
@@ -265,7 +266,7 @@ async def _complete_resource_uri(self, db: Session, ref: Dict[str, Any], arg_val
265266
raise CompletionError("Missing URI template")
266267

267268
# List matching resources
268-
resources = db.execute(select(DbResource).where(DbResource.is_active)).scalars().all()
269+
resources = db.execute(select(DbResource).where(DbResource.enabled)).scalars().all()
269270

270271
# Filter by URI pattern
271272
matches = []

mcpgateway/services/export_service.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ async def _export_prompts(self, db: Session, tags: Optional[List[str]], include_
429429
"description": prompt.description,
430430
"input_schema": input_schema,
431431
"tags": prompt.tags or [],
432-
"is_active": prompt.is_active,
432+
# Use the new `enabled` attribute on prompt objects but keep export key `is_active` for compatibility
433+
"is_active": getattr(prompt, "enabled", getattr(prompt, "is_active", False)),
433434
}
434435

435436
# Convert arguments to input schema format

0 commit comments

Comments
 (0)