Coverage for mcpgateway / common / models.py: 99%

344 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-02-11 07:10 +0000

1# -*- coding: utf-8 -*- 

2"""Location: ./mcpgateway/models.py 

3Copyright 2025 

4SPDX-License-Identifier: Apache-2.0 

5Authors: Mihai Criveti 

6 

7MCP Protocol Type Definitions. 

8This module defines all core MCP protocol types according to the specification. 

9It includes: 

10 - Message content types (text, image, resource) 

11 - Tool definitions and schemas 

12 - Resource types and templates 

13 - Prompt structures 

14 - Protocol initialization types 

15 - Sampling message types 

16 - Capability definitions 

17 

18Examples: 

19 >>> from mcpgateway.common.models import Role, LogLevel, TextContent 

20 >>> Role.USER.value 

21 'user' 

22 >>> Role.ASSISTANT.value 

23 'assistant' 

24 >>> LogLevel.ERROR.value 

25 'error' 

26 >>> LogLevel.INFO.value 

27 'info' 

28 >>> content = TextContent(type='text', text='Hello') 

29 >>> content.text 

30 'Hello' 

31 >>> content.type 

32 'text' 

33""" 

34 

35# Standard 

36from datetime import datetime 

37from enum import Enum 

38from typing import Any, Dict, List, Literal, Optional, Union 

39 

40# Third-Party 

41from pydantic import AnyHttpUrl, AnyUrl, BaseModel, ConfigDict, Field 

42 

43# First-Party 

44from mcpgateway.utils.base_models import BaseModelWithConfigDict, to_camel_case 

45 

46 

47class Role(str, Enum): 

48 """Message role in conversations. 

49 

50 Attributes: 

51 ASSISTANT (str): Indicates the assistant's role. 

52 USER (str): Indicates the user's role. 

53 

54 Examples: 

55 >>> Role.USER.value 

56 'user' 

57 >>> Role.ASSISTANT.value 

58 'assistant' 

59 >>> Role.USER == 'user' 

60 True 

61 >>> list(Role) 

62 [<Role.ASSISTANT: 'assistant'>, <Role.USER: 'user'>] 

63 """ 

64 

65 ASSISTANT = "assistant" 

66 USER = "user" 

67 

68 

69class LogLevel(str, Enum): 

70 """Standard syslog severity levels as defined in RFC 5424. 

71 

72 Attributes: 

73 DEBUG (str): Debug level. 

74 INFO (str): Informational level. 

75 NOTICE (str): Notice level. 

76 WARNING (str): Warning level. 

77 ERROR (str): Error level. 

78 CRITICAL (str): Critical level. 

79 ALERT (str): Alert level. 

80 EMERGENCY (str): Emergency level. 

81 """ 

82 

83 DEBUG = "debug" 

84 INFO = "info" 

85 NOTICE = "notice" 

86 WARNING = "warning" 

87 ERROR = "error" 

88 CRITICAL = "critical" 

89 ALERT = "alert" 

90 EMERGENCY = "emergency" 

91 

92 

93# MCP Protocol Annotations 

94class Annotations(BaseModel): 

95 """Optional annotations for client rendering hints (MCP spec-compliant). 

96 

97 Attributes: 

98 audience (Optional[List[Role]]): Describes who the intended customer of this 

99 object or data is. Can include multiple entries 

100 (e.g., ["user", "assistant"]). 

101 priority (Optional[float]): Describes how important this data is for operating 

102 the server. 1 = most important (effectively required), 

103 0 = least important (entirely optional). 

104 last_modified (Optional[str]): ISO 8601 timestamp of last modification. 

105 Serialized as 'lastModified' in JSON. 

106 """ 

107 

108 audience: Optional[List[Role]] = None 

109 priority: Optional[float] = Field(None, ge=0, le=1) 

110 last_modified: Optional[str] = Field(None, alias="lastModified") 

111 

112 model_config = ConfigDict(populate_by_name=True) 

113 

114 

115class ToolAnnotations(BaseModel): 

116 """Tool behavior hints for clients (MCP spec-compliant). 

117 

118 Attributes: 

119 title (Optional[str]): Human-readable display name for the tool. 

120 read_only_hint (Optional[bool]): If true, tool does not modify its environment. 

121 destructive_hint (Optional[bool]): If true, tool may perform destructive updates. 

122 Only meaningful when read_only_hint == false. 

123 idempotent_hint (Optional[bool]): If true, calling repeatedly with same arguments 

124 has no additional effect. Only meaningful when 

125 read_only_hint == false. 

126 open_world_hint (Optional[bool]): If true, tool may interact with an "open world" 

127 of external entities (e.g., web search). 

128 """ 

129 

130 title: Optional[str] = None 

131 read_only_hint: Optional[bool] = Field(None, alias="readOnlyHint") 

132 destructive_hint: Optional[bool] = Field(None, alias="destructiveHint") 

133 idempotent_hint: Optional[bool] = Field(None, alias="idempotentHint") 

134 open_world_hint: Optional[bool] = Field(None, alias="openWorldHint") 

135 

136 model_config = ConfigDict(populate_by_name=True) 

137 

138 

139# Base content types 

140class TextContent(BaseModelWithConfigDict): 

141 """Text content for messages (MCP spec-compliant). 

142 

143 Attributes: 

144 type (Literal["text"]): The fixed content type identifier for text. 

145 text (str): The actual text message. 

146 annotations (Optional[Annotations]): Optional annotations for the client. 

147 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

148 Serialized as '_meta' in JSON. 

149 

150 Examples: 

151 >>> content = TextContent(type='text', text='Hello World') 

152 >>> content.text 

153 'Hello World' 

154 >>> content.type 

155 'text' 

156 >>> content.model_dump(exclude_none=True) 

157 {'type': 'text', 'text': 'Hello World'} 

158 """ 

159 

160 type: Literal["text"] 

161 text: str 

162 annotations: Optional[Annotations] = None 

163 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

164 

165 

166class ImageContent(BaseModelWithConfigDict): 

167 """Image content for messages (MCP spec-compliant). 

168 

169 Attributes: 

170 type (Literal["image"]): The fixed content type identifier for images. 

171 data (str): Base64-encoded image data for JSON compatibility. 

172 mime_type (str): The MIME type (e.g. "image/png") of the image. 

173 Will be serialized as 'mimeType' in JSON. 

174 annotations (Optional[Annotations]): Optional annotations for the client. 

175 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

176 Serialized as '_meta' in JSON. 

177 """ 

178 

179 type: Literal["image"] 

180 data: str # Base64-encoded string for JSON compatibility 

181 mime_type: str # Will be converted to mimeType by alias_generator 

182 annotations: Optional[Annotations] = None 

183 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

184 

185 

186class AudioContent(BaseModelWithConfigDict): 

187 """Audio content for messages (MCP spec-compliant). 

188 

189 Attributes: 

190 type (Literal["audio"]): The fixed content type identifier for audio. 

191 data (str): Base64-encoded audio data for JSON compatibility. 

192 mime_type (str): The MIME type of the audio (e.g., "audio/wav", "audio/mp3"). 

193 Different providers may support different audio types. 

194 Will be serialized as 'mimeType' in JSON. 

195 annotations (Optional[Annotations]): Optional annotations for the client. 

196 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

197 Serialized as '_meta' in JSON. 

198 """ 

199 

200 type: Literal["audio"] 

201 data: str # Base64-encoded string for JSON compatibility 

202 mime_type: str # Will be converted to mimeType by alias_generator 

203 annotations: Optional[Annotations] = None 

204 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

205 

206 

207class ResourceContents(BaseModelWithConfigDict): 

208 """Base class for resource contents (MCP spec-compliant). 

209 

210 Attributes: 

211 uri (str): The URI of the resource. 

212 mime_type (Optional[str]): The MIME type of the resource, if known. 

213 Will be serialized as 'mimeType' in JSON. 

214 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

215 Serialized as '_meta' in JSON. 

216 """ 

217 

218 uri: str 

219 mime_type: Optional[str] = Field(None, alias="mimeType") 

220 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

221 

222 

223class TextResourceContents(ResourceContents): 

224 """Text contents of a resource (MCP spec-compliant). 

225 

226 Attributes: 

227 text (str): The textual content of the resource. 

228 """ 

229 

230 text: str 

231 

232 

233class BlobResourceContents(ResourceContents): 

234 """Binary contents of a resource (MCP spec-compliant). 

235 

236 Attributes: 

237 blob (str): Base64-encoded binary data of the resource. 

238 """ 

239 

240 blob: str # Base64-encoded binary data 

241 

242 

243# Legacy ResourceContent for backwards compatibility 

244class ResourceContent(BaseModel): 

245 """Resource content that can be embedded (LEGACY - use TextResourceContents or BlobResourceContents). 

246 

247 This class is maintained for backwards compatibility but does not fully comply 

248 with the MCP spec. New code should use TextResourceContents or BlobResourceContents. 

249 

250 Attributes: 

251 type (Literal["resource"]): The fixed content type identifier for resources. 

252 id (str): The ID identifying the resource. 

253 uri (str): The URI of the resource. 

254 mime_type (Optional[str]): The MIME type of the resource, if known. 

255 text (Optional[str]): A textual representation of the resource, if applicable. 

256 blob (Optional[bytes]): Binary data of the resource, if applicable. 

257 """ 

258 

259 type: Literal["resource"] 

260 id: str 

261 uri: str 

262 mime_type: Optional[str] = None 

263 text: Optional[str] = None 

264 blob: Optional[bytes] = None 

265 

266 

267ContentType = Union[TextContent, ImageContent, ResourceContent] 

268 

269 

270# Reference types - needed early for completion 

271class PromptReference(BaseModel): 

272 """Reference to a prompt or prompt template. 

273 

274 Attributes: 

275 type (Literal["ref/prompt"]): The fixed reference type identifier for prompts. 

276 name (str): The unique name of the prompt. 

277 """ 

278 

279 type: Literal["ref/prompt"] 

280 name: str 

281 

282 

283class ResourceReference(BaseModel): 

284 """Reference to a resource or resource template. 

285 

286 Attributes: 

287 type (Literal["ref/resource"]): The fixed reference type identifier for resources. 

288 uri (str): The URI of the resource. 

289 """ 

290 

291 type: Literal["ref/resource"] 

292 uri: str 

293 

294 

295# Completion types 

296class CompleteRequest(BaseModel): 

297 """Request for completion suggestions. 

298 

299 Attributes: 

300 ref (Union[PromptReference, ResourceReference]): A reference to a prompt or resource. 

301 argument (Dict[str, str]): A dictionary containing arguments for the completion. 

302 """ 

303 

304 ref: Union[PromptReference, ResourceReference] 

305 argument: Dict[str, str] 

306 

307 

308class CompleteResult(BaseModel): 

309 """Result for a completion request. 

310 

311 Attributes: 

312 completion (Dict[str, Any]): A dictionary containing the completion results. 

313 """ 

314 

315 completion: Dict[str, Any] = Field(..., description="Completion results") 

316 

317 

318# Implementation info 

319class Implementation(BaseModel): 

320 """MCP implementation information. 

321 

322 Attributes: 

323 name (str): The name of the implementation. 

324 version (str): The version of the implementation. 

325 """ 

326 

327 name: str 

328 version: str 

329 

330 

331# Model preferences 

332class ModelHint(BaseModel): 

333 """Hint for model selection. 

334 

335 Attributes: 

336 name (Optional[str]): An optional hint for the model name. 

337 """ 

338 

339 name: Optional[str] = None 

340 

341 

342class ModelPreferences(BaseModelWithConfigDict): 

343 """Server preferences for model selection. 

344 

345 Uses BaseModelWithConfigDict for automatic snake_case → camelCase conversion. 

346 Fields serialize as: costPriority, speedPriority, intelligencePriority. 

347 

348 Attributes: 

349 cost_priority (float): Priority for cost efficiency (0 to 1). 

350 speed_priority (float): Priority for speed (0 to 1). 

351 intelligence_priority (float): Priority for intelligence (0 to 1). 

352 hints (List[ModelHint]): A list of model hints. 

353 """ 

354 

355 cost_priority: float = Field(ge=0, le=1) 

356 speed_priority: float = Field(ge=0, le=1) 

357 intelligence_priority: float = Field(ge=0, le=1) 

358 hints: List[ModelHint] = [] 

359 

360 

361# Capability types 

362class ClientCapabilities(BaseModel): 

363 """Capabilities that a client may support. 

364 

365 Attributes: 

366 roots (Optional[Dict[str, bool]]): Capabilities related to root management. 

367 sampling (Optional[Dict[str, Any]]): Capabilities related to LLM sampling. 

368 elicitation (Optional[Dict[str, Any]]): Capabilities related to elicitation (MCP 2025-06-18). 

369 experimental (Optional[Dict[str, Dict[str, Any]]]): Experimental capabilities. 

370 """ 

371 

372 roots: Optional[Dict[str, bool]] = None 

373 sampling: Optional[Dict[str, Any]] = None 

374 elicitation: Optional[Dict[str, Any]] = None 

375 experimental: Optional[Dict[str, Dict[str, Any]]] = None 

376 

377 

378class ServerCapabilities(BaseModel): 

379 """Capabilities that a server may support. 

380 

381 Attributes: 

382 prompts (Optional[Dict[str, bool]]): Capability for prompt support. 

383 resources (Optional[Dict[str, bool]]): Capability for resource support. 

384 tools (Optional[Dict[str, bool]]): Capability for tool support. 

385 logging (Optional[Dict[str, Any]]): Capability for logging support. 

386 completions (Optional[Dict[str, Any]]): Capability for completion support. 

387 experimental (Optional[Dict[str, Dict[str, Any]]]): Experimental capabilities. 

388 """ 

389 

390 prompts: Optional[Dict[str, bool]] = None 

391 resources: Optional[Dict[str, bool]] = None 

392 tools: Optional[Dict[str, bool]] = None 

393 logging: Optional[Dict[str, Any]] = None 

394 completions: Optional[Dict[str, Any]] = None 

395 experimental: Optional[Dict[str, Dict[str, Any]]] = None 

396 

397 

398# Initialization types 

399class InitializeRequest(BaseModel): 

400 """Initial request sent from the client to the server. 

401 

402 Attributes: 

403 protocol_version (str): The protocol version (alias: protocolVersion). 

404 capabilities (ClientCapabilities): The client's capabilities. 

405 client_info (Implementation): The client's implementation information (alias: clientInfo). 

406 

407 Note: 

408 The alias settings allow backward compatibility with older Pydantic versions. 

409 """ 

410 

411 protocol_version: str = Field(..., alias="protocolVersion") 

412 capabilities: ClientCapabilities 

413 client_info: Implementation = Field(..., alias="clientInfo") 

414 

415 model_config = ConfigDict( 

416 populate_by_name=True, 

417 ) 

418 

419 

420class InitializeResult(BaseModel): 

421 """Server's response to the initialization request. 

422 

423 Attributes: 

424 protocol_version (str): The protocol version used. 

425 capabilities (ServerCapabilities): The server's capabilities. 

426 server_info (Implementation): The server's implementation information. 

427 instructions (Optional[str]): Optional instructions for the client. 

428 """ 

429 

430 protocol_version: str = Field(..., alias="protocolVersion") 

431 capabilities: ServerCapabilities = Field(..., alias="capabilities") 

432 server_info: Implementation = Field(..., alias="serverInfo") 

433 instructions: Optional[str] = Field(None, alias="instructions") 

434 

435 model_config = ConfigDict( 

436 populate_by_name=True, 

437 ) 

438 

439 

440# Message types 

441class Message(BaseModel): 

442 """A message in a conversation. 

443 

444 Attributes: 

445 role (Role): The role of the message sender. 

446 content (ContentType): The content of the message. 

447 """ 

448 

449 role: Role 

450 content: ContentType 

451 

452 

453class SamplingMessage(BaseModel): 

454 """A message used in LLM sampling requests. 

455 

456 Attributes: 

457 role (Role): The role of the sender. 

458 content (ContentType): The content of the sampling message. 

459 """ 

460 

461 role: Role 

462 content: ContentType 

463 

464 

465class PromptMessage(BaseModelWithConfigDict): 

466 """Message in a prompt (MCP spec-compliant). 

467 

468 A PromptMessage is similar to SamplingMessage but can include additional 

469 content types like ResourceLink and EmbeddedResource. 

470 

471 Attributes: 

472 role (Role): The role of the sender (user or assistant). 

473 content (ContentBlock): The content of the prompt message. 

474 Supports text, images, audio, resource links, and embedded resources. 

475 

476 Note: 

477 Per MCP spec, PromptMessage differs from SamplingMessage in that it can 

478 include ResourceLink and EmbeddedResource content types. 

479 """ 

480 

481 role: Role 

482 content: "ContentBlock" # Uses ContentBlock union (includes ResourceLink and EmbeddedResource) 

483 

484 

485# Sampling types for the client features 

486class CreateMessageResult(BaseModelWithConfigDict): 

487 """Result from a sampling/createMessage request. 

488 

489 Uses BaseModelWithConfigDict for automatic snake_case → camelCase conversion. 

490 The stop_reason field serializes as stopReason per MCP spec. 

491 

492 Attributes: 

493 content (Union[TextContent, ImageContent]): The generated content. 

494 model (str): The model used for generating the content. 

495 role (Role): The role associated with the content. 

496 stop_reason (Optional[str]): An optional reason for why sampling stopped. 

497 """ 

498 

499 content: Union[TextContent, ImageContent] 

500 model: str 

501 role: Role 

502 stop_reason: Optional[str] = None 

503 

504 

505# Prompt types 

506class PromptArgument(BaseModelWithConfigDict): 

507 """An argument that can be passed to a prompt (MCP spec-compliant, extends BaseMetadata). 

508 

509 Attributes: 

510 name (str): The name of the argument. 

511 title (Optional[str]): Human-readable title for the argument. 

512 description (Optional[str]): An optional description of the argument. 

513 required (bool): Whether the argument is required. Defaults to False. 

514 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

515 Serialized as '_meta' in JSON. 

516 """ 

517 

518 name: str 

519 title: Optional[str] = None 

520 description: Optional[str] = None 

521 required: bool = False 

522 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

523 

524 

525class Prompt(BaseModelWithConfigDict): 

526 """A prompt template offered by the server (MCP spec-compliant). 

527 

528 Attributes: 

529 name (str): The unique name of the prompt. 

530 description (Optional[str]): A description of the prompt. 

531 arguments (List[PromptArgument]): A list of expected prompt arguments. 

532 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

533 Serialized as '_meta' in JSON. 

534 """ 

535 

536 name: str 

537 description: Optional[str] = None 

538 arguments: List[PromptArgument] = [] 

539 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

540 

541 

542class PromptResult(BaseModel): 

543 """Result of rendering a prompt template. 

544 

545 Attributes: 

546 messages (List[Message]): The list of messages produced by rendering the prompt. 

547 description (Optional[str]): An optional description of the rendered result. 

548 """ 

549 

550 messages: List[Message] 

551 description: Optional[str] = None 

552 

553 

554class CommonAttributes(BaseModel): 

555 """Common attributes for tools and gateways. 

556 

557 Attributes: 

558 name (str): The unique name of the tool. 

559 url (AnyHttpUrl): The URL of the tool. 

560 description (Optional[str]): A description of the tool. 

561 created_at (Optional[datetime]): The time at which the tool was created. 

562 update_at (Optional[datetime]): The time at which the tool was updated. 

563 enabled (Optional[bool]): If the tool is enabled. 

564 reachable (Optional[bool]): If the tool is currently reachable. 

565 tags (Optional[list[Dict[str,str]]]): A list of meta data tags describing the tool. 

566 created_by (Optional[str]): The person that created the tool. 

567 created_from_ip (Optional[str]): The client IP that created the tool. 

568 created_via (Optional[str]): How the tool was created (e.g., ui). 

569 created_user_agent (Optioanl[str]): The client user agent. 

570 modified_by (Optional[str]): The person that modified the tool. 

571 modified_from_ip (Optional[str]): The client IP that modified the tool. 

572 modified_via (Optional[str]): How the tool was modified (e.g., ui). 

573 modified_user_agent (Optioanl[str]): The client user agent. 

574 import_batch_id (Optional[str]): The id of the batch file that imported the tool. 

575 federation_source (Optional[str]): The federation source of the tool 

576 version (Optional[int]): The version of the tool. 

577 team_id (Optional[str]): The id of the team that created the tool. 

578 owner_email (Optional[str]): Tool owner's email. 

579 visibility (Optional[str]): Visibility of the tool (e.g., public, private). 

580 """ 

581 

582 name: str 

583 url: AnyHttpUrl 

584 description: Optional[str] = None 

585 created_at: Optional[datetime] = None 

586 updated_at: Optional[datetime] = None 

587 enabled: Optional[bool] = None 

588 reachable: Optional[bool] = None 

589 auth_type: Optional[str] = None 

590 tags: Optional[list[Dict[str, str]]] = None 

591 # Comprehensive metadata for audit tracking 

592 created_by: Optional[str] = None 

593 created_from_ip: Optional[str] = None 

594 created_via: Optional[str] = None 

595 created_user_agent: Optional[str] = None 

596 

597 modified_by: Optional[str] = None 

598 modified_from_ip: Optional[str] = None 

599 modified_via: Optional[str] = None 

600 modified_user_agent: Optional[str] = None 

601 

602 import_batch_id: Optional[str] = None 

603 federation_source: Optional[str] = None 

604 version: Optional[int] = None 

605 # Team scoping fields for resource organization 

606 team_id: Optional[str] = None 

607 owner_email: Optional[str] = None 

608 visibility: Optional[str] = None 

609 

610 

611# Tool types 

612class Tool(CommonAttributes): 

613 """A tool that can be invoked. 

614 

615 Attributes: 

616 original_name (str): The original supplied name of the tool before imported by the gateway. 

617 integrationType (str): The integration type of the tool (e.g. MCP or REST). 

618 requestType (str): The HTTP method used to invoke the tool (GET, POST, PUT, DELETE, SSE, STDIO). 

619 headers (Dict[str, Any]): A JSON object representing HTTP headers. 

620 input_schema (Dict[str, Any]): A JSON Schema for validating the tool's input. 

621 output_schema (Optional[Dict[str, Any]]): A JSON Schema for validating the tool's output. 

622 annotations (Optional[Dict[str, Any]]): Tool annotations for behavior hints. 

623 auth_username (Optional[str]): The username for basic authentication. 

624 auth_password (Optional[str]): The password for basic authentication. 

625 auth_token (Optional[str]): The token for bearer authentication. 

626 jsonpath_filter (Optional[str]): Filter the tool based on a JSON path expression. 

627 custom_name (Optional[str]): Custom tool name. 

628 custom_name_slug (Optional[str]): Alternative custom tool name. 

629 display_name (Optional[str]): Display name. 

630 gateway_id (Optional[str]): The gateway id on which the tool is hosted. 

631 """ 

632 

633 model_config = ConfigDict(from_attributes=True) 

634 original_name: Optional[str] = None 

635 integration_type: str = "MCP" 

636 request_type: str = "SSE" 

637 headers: Optional[Dict[str, Any]] = Field(default_factory=dict) 

638 input_schema: Dict[str, Any] = Field(default_factory=lambda: {"type": "object", "properties": {}}) 

639 output_schema: Optional[Dict[str, Any]] = Field(default=None, description="JSON Schema for validating the tool's output") 

640 annotations: Optional[Dict[str, Any]] = Field(default_factory=dict, description="Tool annotations for behavior hints") 

641 auth_username: Optional[str] = None 

642 auth_password: Optional[str] = None 

643 auth_token: Optional[str] = None 

644 jsonpath_filter: Optional[str] = None 

645 

646 # custom_name,custom_name_slug, display_name 

647 custom_name: Optional[str] = None 

648 custom_name_slug: Optional[str] = None 

649 display_name: Optional[str] = None 

650 

651 # Federation relationship with a local gateway 

652 gateway_id: Optional[str] = None 

653 

654 

655class CallToolResult(BaseModelWithConfigDict): 

656 """Result of a tool invocation (MCP spec-compliant). 

657 

658 Attributes: 

659 content (List[ContentType]): A list of content items returned by the tool. 

660 is_error (bool): Flag indicating if the tool call resulted in an error. 

661 Will be serialized as 'isError' in JSON. 

662 structured_content (Optional[Dict[str, Any]]): Optional structured JSON output. 

663 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

664 Serialized as '_meta' in JSON. 

665 

666 Note: 

667 This class uses BaseModelWithConfigDict which automatically converts 

668 is_error to isError in JSON output via the alias_generator. 

669 """ 

670 

671 content: List["ContentBlock"] # Uses ContentBlock union for full MCP spec support 

672 is_error: Optional[bool] = Field(default=False, alias="isError") 

673 structured_content: Optional[Dict[str, Any]] = Field(None, alias="structuredContent") 

674 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

675 

676 

677# Legacy alias for backwards compatibility 

678ToolResult = CallToolResult 

679 

680 

681# Resource types 

682class Resource(BaseModelWithConfigDict): 

683 """A resource available from the server (MCP spec-compliant). 

684 

685 Attributes: 

686 uri (str): The unique URI of the resource. 

687 name (str): The human-readable name of the resource. 

688 description (Optional[str]): A description of the resource. 

689 mime_type (Optional[str]): The MIME type of the resource. 

690 Will be serialized as 'mimeType' in JSON. 

691 size (Optional[int]): The size of the resource. 

692 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

693 Serialized as '_meta' in JSON. 

694 """ 

695 

696 uri: str 

697 name: str 

698 description: Optional[str] = None 

699 mime_type: Optional[str] = None 

700 size: Optional[int] = None 

701 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

702 

703 

704class ResourceTemplate(BaseModelWithConfigDict): 

705 """A template for constructing resource URIs (MCP spec-compliant). 

706 

707 Attributes: 

708 id (Optional[str]): Unique identifier for resource 

709 uri_template (str): The URI template string. 

710 name (str): The unique name of the template. 

711 description (Optional[str]): A description of the template. 

712 mime_type (Optional[str]): The MIME type associated with the template. 

713 Will be serialized as 'mimeType' in JSON. 

714 annotations (Optional[Annotations]): Optional annotations for client rendering hints. 

715 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

716 Serialized as '_meta' in JSON. 

717 """ 

718 

719 # ✅ DB field name: uri_template 

720 # ✅ API (JSON) alias: 

721 id: Optional[str] = None 

722 uri_template: str = Field(..., alias="uriTemplate") 

723 name: str 

724 description: Optional[str] = None 

725 mime_type: Optional[str] = None 

726 annotations: Optional[Dict[str, Any]] = None 

727 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

728 

729 

730class ResourceLink(Resource): 

731 """A resource link included in prompts or tool results (MCP spec-compliant). 

732 

733 Note: Inherits uri, name, description, mime_type, size, meta from Resource. 

734 Per MCP spec, this extends Resource and adds a type discriminator. 

735 

736 Attributes: 

737 type (Literal["resource_link"]): The fixed type identifier for resource links. 

738 """ 

739 

740 type: Literal["resource_link"] = "resource_link" 

741 

742 

743class EmbeddedResource(BaseModelWithConfigDict): 

744 """The contents of a resource, embedded into a prompt or tool call result (MCP spec-compliant). 

745 

746 It is up to the client how best to render embedded resources for the benefit 

747 of the LLM and/or the user. 

748 

749 Attributes: 

750 type (Literal["resource"]): The fixed type identifier for embedded resources. 

751 resource (Union[TextResourceContents, BlobResourceContents]): The resource contents. 

752 annotations (Optional[Annotations]): Optional annotations for the client. 

753 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

754 Serialized as '_meta' in JSON. 

755 """ 

756 

757 type: Literal["resource"] = "resource" 

758 resource: Union[TextResourceContents, BlobResourceContents] 

759 annotations: Optional[Annotations] = None 

760 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

761 

762 

763# MCP spec-compliant ContentBlock union for prompts and tool results 

764# Per spec: ContentBlock can include ResourceLink and EmbeddedResource 

765ContentBlock = Union[TextContent, ImageContent, AudioContent, ResourceLink, EmbeddedResource] 

766 

767 

768class ListResourceTemplatesResult(BaseModel): 

769 """The server's response to a resources/templates/list request from the client. 

770 

771 Attributes: 

772 meta (Optional[Dict[str, Any]]): Reserved property for metadata. 

773 next_cursor (Optional[str]): Pagination cursor for the next page of results. 

774 resource_templates (List[ResourceTemplate]): List of resource templates. 

775 """ 

776 

777 meta: Optional[Dict[str, Any]] = Field( 

778 None, alias="_meta", description="This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses." 

779 ) 

780 next_cursor: Optional[str] = Field(None, description="An opaque token representing the pagination position after the last returned result.\nIf present, there may be more results available.") 

781 resource_templates: List[ResourceTemplate] = Field(default_factory=list, description="List of resource templates available on the server") 

782 

783 model_config = ConfigDict( 

784 populate_by_name=True, 

785 ) 

786 

787 

788# Elicitation types (MCP 2025-06-18) 

789class ElicitationCapability(BaseModelWithConfigDict): 

790 """Client capability for elicitation operations (MCP 2025-06-18). 

791 

792 Per MCP spec: Clients that support elicitation MUST declare this capability 

793 during initialization. Elicitation allows servers to request structured 

794 information from users through the client during interactive workflows. 

795 

796 Example: 

797 {"capabilities": {"elicitation": {}}} 

798 """ 

799 

800 # Empty object per MCP spec, follows MCP SDK pattern 

801 model_config = ConfigDict(extra="allow") 

802 

803 

804class ElicitRequestParams(BaseModelWithConfigDict): 

805 """Parameters for elicitation/create requests (MCP spec-compliant). 

806 

807 Elicitation requests allow servers to ask for user input with a structured 

808 schema. The schema is restricted to flat objects with primitive types only. 

809 

810 Attributes: 

811 message: Human-readable message to present to user 

812 requestedSchema: JSON Schema defining expected response structure. 

813 Per MCP spec, must be type 'object' with primitive properties only: 

814 - string (optional format: email, uri, date, date-time) 

815 - number/integer (optional min/max) 

816 - boolean 

817 - enum (string values) 

818 No nested objects or arrays allowed. 

819 

820 Example: 

821 { 

822 "message": "Please provide your contact information", 

823 "requestedSchema": { 

824 "type": "object", 

825 "properties": { 

826 "name": {"type": "string", "description": "Your full name"}, 

827 "email": {"type": "string", "format": "email"} 

828 }, 

829 "required": ["name", "email"] 

830 } 

831 } 

832 """ 

833 

834 message: str 

835 requestedSchema: Dict[str, Any] # JSON Schema (validated by ElicitationService) # noqa: N815 (MCP spec requires camelCase) 

836 model_config = ConfigDict(extra="allow") 

837 

838 

839class ElicitResult(BaseModelWithConfigDict): 

840 """Client response to elicitation request (MCP spec three-action model). 

841 

842 The MCP specification defines three distinct user actions to differentiate 

843 between explicit approval, explicit rejection, and dismissal without choice. 

844 

845 Attributes: 

846 action: User's response action: 

847 - "accept": User explicitly approved and submitted data 

848 (content field MUST be populated) 

849 - "decline": User explicitly declined the request 

850 (content typically None/omitted) 

851 - "cancel": User dismissed without making an explicit choice 

852 (content typically None/omitted) 

853 content: Submitted form data matching requestedSchema. 

854 Only present when action is "accept". 

855 Contains primitive values: str, int, float, bool, or None. 

856 

857 Examples: 

858 Accept response: 

859 {"action": "accept", "content": {"name": "John", "email": "john@example.com"}} 

860 

861 Decline response: 

862 {"action": "decline"} 

863 

864 Cancel response: 

865 {"action": "cancel"} 

866 """ 

867 

868 action: Literal["accept", "decline", "cancel"] 

869 content: Optional[Dict[str, Union[str, int, float, bool, None]]] = None 

870 model_config = ConfigDict(extra="allow") 

871 

872 

873# Root types 

874class FileUrl(AnyUrl): 

875 """A specialized URL type for local file-scheme resources. 

876 

877 Key characteristics 

878 ------------------- 

879 * Scheme restricted - only the "file" scheme is permitted 

880 (e.g. file:///path/to/file.txt). 

881 * No host required - "file" URLs typically omit a network host; 

882 therefore, the host component is not mandatory. 

883 * String-friendly equality - developers naturally expect 

884 FileUrl("file:///data") == "file:///data" to evaluate True. 

885 AnyUrl (Pydantic) does not implement that, so we override 

886 __eq__ to compare against plain strings transparently. 

887 Hash semantics are kept consistent by delegating to the parent class. 

888 

889 Examples 

890 -------- 

891 >>> url = FileUrl("file:///etc/hosts") 

892 >>> url.scheme 

893 'file' 

894 >>> url == "file:///etc/hosts" 

895 True 

896 >>> {"path": url} # hashable 

897 {'path': FileUrl('file:///etc/hosts')} 

898 

899 Notes 

900 ----- 

901 The override does not interfere with comparisons to other 

902 AnyUrl/FileUrl instances; those still use the superclass 

903 implementation. 

904 """ 

905 

906 # Restrict to the "file" scheme and omit host requirement 

907 allowed_schemes = {"file"} 

908 host_required = False 

909 

910 def __eq__(self, other): # type: ignore[override] 

911 """Return True when other is an equivalent URL or string. 

912 

913 If other is a str it is coerced with str(self) for comparison; 

914 otherwise defer to AnyUrl's comparison. 

915 

916 Args: 

917 other (Any): The object to compare against. May be a str, FileUrl, or AnyUrl. 

918 

919 Returns: 

920 bool: True if the other value is equal to this URL, either as a string 

921 or as another URL object. False otherwise. 

922 """ 

923 if isinstance(other, str): 923 ↛ 925line 923 didn't jump to line 925 because the condition on line 923 was always true

924 return str(self) == other 

925 return super().__eq__(other) 

926 

927 # Keep hashing behaviour aligned with equality 

928 __hash__ = AnyUrl.__hash__ 

929 

930 

931class Root(BaseModelWithConfigDict): 

932 """A root directory or file (MCP spec-compliant). 

933 

934 Attributes: 

935 uri (Union[FileUrl, AnyUrl]): The unique identifier for the root. 

936 name (Optional[str]): An optional human-readable name. 

937 meta (Optional[Dict[str, Any]]): Optional metadata for protocol extension. 

938 Serialized as '_meta' in JSON. 

939 """ 

940 

941 model_config = ConfigDict( 

942 arbitrary_types_allowed=True, 

943 from_attributes=True, 

944 alias_generator=to_camel_case, 

945 populate_by_name=True, 

946 use_enum_values=True, 

947 extra="ignore", 

948 json_schema_extra={"nullable": True}, 

949 ) 

950 

951 uri: Union[FileUrl, AnyUrl] = Field(..., description="Unique identifier for the root") 

952 name: Optional[str] = Field(None, description="Optional human-readable name") 

953 meta: Optional[Dict[str, Any]] = Field(None, alias="_meta") 

954 

955 

956# Progress types 

957class ProgressToken(BaseModel): 

958 """Token for associating progress notifications. 

959 

960 Attributes: 

961 value (Union[str, int]): The token value. 

962 """ 

963 

964 value: Union[str, int] 

965 

966 

967class Progress(BaseModel): 

968 """Progress update for long-running operations. 

969 

970 Attributes: 

971 progress_token (ProgressToken): The token associated with the progress update. 

972 progress (float): The current progress value. 

973 total (Optional[float]): The total progress value, if known. 

974 """ 

975 

976 progress_token: ProgressToken 

977 progress: float 

978 total: Optional[float] = None 

979 

980 

981# JSON-RPC types 

982class JSONRPCRequest(BaseModel): 

983 """JSON-RPC 2.0 request. 

984 

985 Attributes: 

986 jsonrpc (Literal["2.0"]): The JSON-RPC version. 

987 id (Optional[Union[str, int]]): The request identifier. 

988 method (str): The method name. 

989 params (Optional[Dict[str, Any]]): The parameters for the request. 

990 """ 

991 

992 jsonrpc: Literal["2.0"] 

993 id: Optional[Union[str, int]] = None 

994 method: str 

995 params: Optional[Dict[str, Any]] = None 

996 

997 

998class JSONRPCResponse(BaseModel): 

999 """JSON-RPC 2.0 response. 

1000 

1001 Attributes: 

1002 jsonrpc (Literal["2.0"]): The JSON-RPC version. 

1003 id (Optional[Union[str, int]]): The request identifier. 

1004 result (Optional[Any]): The result of the request. 

1005 error (Optional[Dict[str, Any]]): The error object if an error occurred. 

1006 """ 

1007 

1008 jsonrpc: Literal["2.0"] 

1009 id: Optional[Union[str, int]] = None 

1010 result: Optional[Any] = None 

1011 error: Optional[Dict[str, Any]] = None 

1012 

1013 

1014class JSONRPCError(BaseModel): 

1015 """JSON-RPC 2.0 error. 

1016 

1017 Attributes: 

1018 code (int): The error code. 

1019 message (str): A short description of the error. 

1020 data (Optional[Any]): Additional data about the error. 

1021 """ 

1022 

1023 code: int 

1024 message: str 

1025 data: Optional[Any] = None 

1026 

1027 

1028# Global configuration types 

1029class GlobalConfig(BaseModel): 

1030 """Global server configuration. 

1031 

1032 Attributes: 

1033 passthrough_headers (Optional[List[str]]): List of headers allowed to be passed through globally 

1034 """ 

1035 

1036 passthrough_headers: Optional[List[str]] = Field(default=None, description="List of headers allowed to be passed through globally") 

1037 

1038 

1039# Transport message types 

1040class SSEEvent(BaseModel): 

1041 """Server-Sent Events message. 

1042 

1043 Attributes: 

1044 id (Optional[str]): The event identifier. 

1045 event (Optional[str]): The event type. 

1046 data (str): The event data. 

1047 retry (Optional[int]): The retry timeout in milliseconds. 

1048 """ 

1049 

1050 id: Optional[str] = None 

1051 event: Optional[str] = None 

1052 data: str 

1053 retry: Optional[int] = None 

1054 

1055 

1056class WebSocketMessage(BaseModel): 

1057 """WebSocket protocol message. 

1058 

1059 Attributes: 

1060 type (str): The type of the WebSocket message. 

1061 data (Any): The message data. 

1062 """ 

1063 

1064 type: str 

1065 data: Any 

1066 

1067 

1068# Notification types 

1069class ResourceUpdateNotification(BaseModel): 

1070 """Notification of resource changes. 

1071 

1072 Attributes: 

1073 method (Literal["notifications/resources/updated"]): The notification method. 

1074 uri (str): The URI of the updated resource. 

1075 """ 

1076 

1077 method: Literal["notifications/resources/updated"] 

1078 uri: str 

1079 

1080 

1081class ResourceListChangedNotification(BaseModel): 

1082 """Notification of resource list changes. 

1083 

1084 Attributes: 

1085 method (Literal["notifications/resources/list_changed"]): The notification method. 

1086 """ 

1087 

1088 method: Literal["notifications/resources/list_changed"] 

1089 

1090 

1091class PromptListChangedNotification(BaseModel): 

1092 """Notification of prompt list changes. 

1093 

1094 Attributes: 

1095 method (Literal["notifications/prompts/list_changed"]): The notification method. 

1096 """ 

1097 

1098 method: Literal["notifications/prompts/list_changed"] 

1099 

1100 

1101class ToolListChangedNotification(BaseModel): 

1102 """Notification of tool list changes. 

1103 

1104 Attributes: 

1105 method (Literal["notifications/tools/list_changed"]): The notification method. 

1106 """ 

1107 

1108 method: Literal["notifications/tools/list_changed"] 

1109 

1110 

1111class CancelledNotification(BaseModel): 

1112 """Notification of request cancellation. 

1113 

1114 Attributes: 

1115 method (Literal["notifications/cancelled"]): The notification method. 

1116 request_id (Union[str, int]): The ID of the cancelled request. 

1117 reason (Optional[str]): An optional reason for cancellation. 

1118 """ 

1119 

1120 method: Literal["notifications/cancelled"] 

1121 request_id: Union[str, int] 

1122 reason: Optional[str] = None 

1123 

1124 

1125class ProgressNotification(BaseModel): 

1126 """Notification of operation progress. 

1127 

1128 Attributes: 

1129 method (Literal["notifications/progress"]): The notification method. 

1130 progress_token (ProgressToken): The token associated with the progress. 

1131 progress (float): The current progress value. 

1132 total (Optional[float]): The total progress value, if known. 

1133 """ 

1134 

1135 method: Literal["notifications/progress"] 

1136 progress_token: ProgressToken 

1137 progress: float 

1138 total: Optional[float] = None 

1139 

1140 

1141class LoggingNotification(BaseModel): 

1142 """Notification of log messages. 

1143 

1144 Attributes: 

1145 method (Literal["notifications/message"]): The notification method. 

1146 level (LogLevel): The log level of the message. 

1147 logger (Optional[str]): The logger name. 

1148 data (Any): The log message data. 

1149 """ 

1150 

1151 method: Literal["notifications/message"] 

1152 level: LogLevel 

1153 logger: Optional[str] = None 

1154 data: Any 

1155 

1156 

1157# Federation types 

1158class FederatedTool(Tool): 

1159 """A tool from a federated gateway. 

1160 

1161 Attributes: 

1162 gateway_id (str): The identifier of the gateway. 

1163 gateway_name (str): The name of the gateway. 

1164 """ 

1165 

1166 gateway_id: str 

1167 gateway_name: str 

1168 

1169 

1170class FederatedResource(Resource): 

1171 """A resource from a federated gateway. 

1172 

1173 Attributes: 

1174 gateway_id (str): The identifier of the gateway. 

1175 gateway_name (str): The name of the gateway. 

1176 """ 

1177 

1178 gateway_id: str 

1179 gateway_name: str 

1180 

1181 

1182class FederatedPrompt(Prompt): 

1183 """A prompt from a federated gateway. 

1184 

1185 Attributes: 

1186 gateway_id (str): The identifier of the gateway. 

1187 gateway_name (str): The name of the gateway. 

1188 """ 

1189 

1190 gateway_id: str 

1191 gateway_name: str 

1192 

1193 

1194class Gateway(CommonAttributes): 

1195 """A federated gateway peer. 

1196 

1197 Attributes: 

1198 id (str): The unique identifier for the gateway. 

1199 name (str): The name of the gateway. 

1200 url (AnyHttpUrl): The URL of the gateway. 

1201 capabilities (ServerCapabilities): The capabilities of the gateway. 

1202 last_seen (Optional[datetime]): Timestamp when the gateway was last seen. 

1203 """ 

1204 

1205 model_config = ConfigDict(from_attributes=True) 

1206 id: str 

1207 capabilities: ServerCapabilities 

1208 last_seen: Optional[datetime] = None 

1209 slug: str 

1210 transport: str 

1211 last_seen: Optional[datetime] 

1212 # Header passthrough configuration 

1213 passthrough_headers: Optional[list[str]] # Store list of strings as JSON array 

1214 # Request type and authentication fields 

1215 auth_value: Optional[str | dict] 

1216 

1217 

1218# ===== RBAC Models ===== 

1219 

1220 

1221class RBACRole(BaseModel): 

1222 """Role model for RBAC system. 

1223 

1224 Represents roles that can be assigned to users with specific permissions. 

1225 Supports global, team, and personal scopes with role inheritance. 

1226 

1227 Attributes: 

1228 id: Unique role identifier 

1229 name: Human-readable role name 

1230 description: Role description and purpose 

1231 scope: Role scope ('global', 'team', 'personal') 

1232 permissions: List of permission strings 

1233 inherits_from: Parent role ID for inheritance 

1234 created_by: Email of user who created the role 

1235 is_system_role: Whether this is a system-defined role 

1236 is_active: Whether the role is currently active 

1237 created_at: Role creation timestamp 

1238 updated_at: Role last modification timestamp 

1239 

1240 Examples: 

1241 >>> from datetime import datetime 

1242 >>> role = RBACRole( 

1243 ... id="role-123", 

1244 ... name="team_admin", 

1245 ... description="Team administrator with member management rights", 

1246 ... scope="team", 

1247 ... permissions=["teams.manage_members", "resources.create"], 

1248 ... created_by="admin@example.com", 

1249 ... created_at=datetime(2023, 1, 1), 

1250 ... updated_at=datetime(2023, 1, 1) 

1251 ... ) 

1252 >>> role.name 

1253 'team_admin' 

1254 >>> "teams.manage_members" in role.permissions 

1255 True 

1256 """ 

1257 

1258 id: str = Field(..., description="Unique role identifier") 

1259 name: str = Field(..., description="Human-readable role name") 

1260 description: Optional[str] = Field(None, description="Role description and purpose") 

1261 scope: str = Field(..., description="Role scope", pattern="^(global|team|personal)$") 

1262 permissions: List[str] = Field(..., description="List of permission strings") 

1263 inherits_from: Optional[str] = Field(None, description="Parent role ID for inheritance") 

1264 created_by: str = Field(..., description="Email of user who created the role") 

1265 is_system_role: bool = Field(False, description="Whether this is a system-defined role") 

1266 is_active: bool = Field(True, description="Whether the role is currently active") 

1267 created_at: datetime = Field(..., description="Role creation timestamp") 

1268 updated_at: datetime = Field(..., description="Role last modification timestamp") 

1269 

1270 

1271class UserRoleAssignment(BaseModel): 

1272 """User role assignment model. 

1273 

1274 Represents the assignment of roles to users in specific scopes (global, team, personal). 

1275 Includes metadata about who granted the role and when it expires. 

1276 

1277 Attributes: 

1278 id: Unique assignment identifier 

1279 user_email: Email of the user assigned the role 

1280 role_id: ID of the assigned role 

1281 scope: Assignment scope ('global', 'team', 'personal') 

1282 scope_id: Team ID if team-scoped, None otherwise 

1283 granted_by: Email of user who granted this role 

1284 granted_at: Timestamp when role was granted 

1285 expires_at: Optional expiration timestamp 

1286 is_active: Whether the assignment is currently active 

1287 

1288 Examples: 

1289 >>> from datetime import datetime 

1290 >>> user_role = UserRoleAssignment( 

1291 ... id="assignment-123", 

1292 ... user_email="user@example.com", 

1293 ... role_id="team-admin-123", 

1294 ... scope="team", 

1295 ... scope_id="team-engineering-456", 

1296 ... granted_by="admin@example.com", 

1297 ... granted_at=datetime(2023, 1, 1) 

1298 ... ) 

1299 >>> user_role.scope 

1300 'team' 

1301 >>> user_role.is_active 

1302 True 

1303 """ 

1304 

1305 id: str = Field(..., description="Unique assignment identifier") 

1306 user_email: str = Field(..., description="Email of the user assigned the role") 

1307 role_id: str = Field(..., description="ID of the assigned role") 

1308 scope: str = Field(..., description="Assignment scope", pattern="^(global|team|personal)$") 

1309 scope_id: Optional[str] = Field(None, description="Team ID if team-scoped, None otherwise") 

1310 granted_by: str = Field(..., description="Email of user who granted this role") 

1311 granted_at: datetime = Field(..., description="Timestamp when role was granted") 

1312 expires_at: Optional[datetime] = Field(None, description="Optional expiration timestamp") 

1313 is_active: bool = Field(True, description="Whether the assignment is currently active") 

1314 

1315 

1316class PermissionAudit(BaseModel): 

1317 """Permission audit log model. 

1318 

1319 Records all permission checks for security auditing and compliance. 

1320 Includes details about the user, permission, resource, and result. 

1321 

1322 Attributes: 

1323 id: Unique audit log entry identifier 

1324 timestamp: When the permission check occurred 

1325 user_email: Email of user being checked 

1326 permission: Permission being checked (e.g., 'tools.create') 

1327 resource_type: Type of resource (e.g., 'tools', 'teams') 

1328 resource_id: Specific resource ID if applicable 

1329 team_id: Team context if applicable 

1330 granted: Whether permission was granted 

1331 roles_checked: JSON of roles that were checked 

1332 ip_address: IP address of the request 

1333 user_agent: User agent string 

1334 

1335 Examples: 

1336 >>> from datetime import datetime 

1337 >>> audit_log = PermissionAudit( 

1338 ... id=1, 

1339 ... timestamp=datetime(2023, 1, 1), 

1340 ... user_email="user@example.com", 

1341 ... permission="tools.create", 

1342 ... resource_type="tools", 

1343 ... granted=True, 

1344 ... roles_checked={"roles": ["team_admin"]} 

1345 ... ) 

1346 >>> audit_log.granted 

1347 True 

1348 >>> audit_log.permission 

1349 'tools.create' 

1350 """ 

1351 

1352 id: int = Field(..., description="Unique audit log entry identifier") 

1353 timestamp: datetime = Field(..., description="When the permission check occurred") 

1354 user_email: Optional[str] = Field(None, description="Email of user being checked") 

1355 permission: str = Field(..., description="Permission being checked") 

1356 resource_type: Optional[str] = Field(None, description="Type of resource") 

1357 resource_id: Optional[str] = Field(None, description="Specific resource ID if applicable") 

1358 team_id: Optional[str] = Field(None, description="Team context if applicable") 

1359 granted: bool = Field(..., description="Whether permission was granted") 

1360 roles_checked: Optional[Dict] = Field(None, description="JSON of roles that were checked") 

1361 ip_address: Optional[str] = Field(None, description="IP address of the request") 

1362 user_agent: Optional[str] = Field(None, description="User agent string") 

1363 

1364 

1365# Permission constants are imported from db.py to avoid duplication 

1366# Use Permissions class from mcpgateway.db instead of duplicate SystemPermissions 

1367 

1368 

1369class TransportType(str, Enum): 

1370 """ 

1371 Enumeration of supported transport mechanisms for communication between components. 

1372 

1373 Attributes: 

1374 SSE (str): Server-Sent Events transport. 

1375 HTTP (str): Standard HTTP-based transport. 

1376 STDIO (str): Standard input/output transport. 

1377 STREAMABLEHTTP (str): HTTP transport with streaming. 

1378 GRPC (str): gRPC transport for external plugins. 

1379 """ 

1380 

1381 SSE = "SSE" 

1382 HTTP = "HTTP" 

1383 STDIO = "STDIO" 

1384 STREAMABLEHTTP = "STREAMABLEHTTP" 

1385 GRPC = "GRPC"