Files
ITWorx_MCP_Hub-Public/packages/connector_kit/contracts.py
T

81 lines
2.5 KiB
Python

"""Shared bounded connector contracts used by all first-party connectors."""
from __future__ import annotations
from datetime import UTC, datetime
from typing import Any
from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field
class ConnectorContext(BaseModel):
"""Validated invocation scope supplied by the Hub, never by target content."""
model_config = ConfigDict(extra="forbid", frozen=True)
workspace_id: UUID
project_id: UUID
project_slug: str = Field(pattern=r"^[a-z0-9][a-z0-9-]{0,62}$")
environment: str = Field(pattern=r"^[a-z0-9][a-z0-9-]{0,31}$")
client_id: UUID | None = None
correlation_id: str | None = Field(default=None, pattern=r"^[A-Za-z0-9._:-]{1,128}$")
class PageRequest(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
limit: int = Field(default=20, ge=1, le=100)
cursor: str | None = Field(default=None, max_length=500)
class ResultMeta(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
project: str
environment: str
source: str
truncated: bool = False
next_cursor: str | None = None
generated_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
class ResultEnvelope[T](BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
data: T
meta: ResultMeta
warnings: tuple[str, ...] = ()
class HealthSnapshot(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
status: str = Field(pattern=r"^(healthy|ready|degraded|failed)$")
component: str = Field(min_length=1, max_length=100)
details: dict[str, Any] = Field(default_factory=dict)
class ToolPublication(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
canonical_name: str = Field(pattern=r"^[a-z0-9]+(?:\.[a-z0-9-]+){2,}$")
version: str = Field(pattern=r"^\d+\.\d+\.\d+$")
connector_type: str = Field(min_length=1, max_length=64)
read_only: bool = True
risk_class: str = Field(pattern=r"^R[0-9]+$")
input_schema: dict[str, Any]
output_schema: dict[str, Any]
required_scopes: tuple[str, ...] = ()
class ResourcePublication(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
uri_template: str = Field(min_length=1, max_length=2048)
connector_type: str = Field(min_length=1, max_length=64)
risk_class: str = Field(pattern=r"^R[0-9]+$")
mime_types: tuple[str, ...] = ()
max_bytes: int = Field(ge=1, le=4 * 1024 * 1024)
required_scopes: tuple[str, ...] = ()