Coverage for mcpgateway/types.py: 99%
211 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-22 12:53 +0100
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-22 12:53 +0100
1# -*- coding: utf-8 -*-
2"""MCP Protocol Type Definitions.
4Copyright 2025
5SPDX-License-Identifier: Apache-2.0
6Authors: Mihai Criveti
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"""
19from datetime import datetime
20from enum import Enum
21from typing import Any, Dict, List, Literal, Optional, Union
23from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field
26class Role(str, Enum):
27 """Message role in conversations.
29 Attributes:
30 ASSISTANT (str): Indicates the assistant's role.
31 USER (str): Indicates the user's role.
32 """
34 ASSISTANT = "assistant"
35 USER = "user"
38class LogLevel(str, Enum):
39 """Standard syslog severity levels as defined in RFC 5424.
41 Attributes:
42 DEBUG (str): Debug level.
43 INFO (str): Informational level.
44 NOTICE (str): Notice level.
45 WARNING (str): Warning level.
46 ERROR (str): Error level.
47 CRITICAL (str): Critical level.
48 ALERT (str): Alert level.
49 EMERGENCY (str): Emergency level.
50 """
52 DEBUG = "debug"
53 INFO = "info"
54 NOTICE = "notice"
55 WARNING = "warning"
56 ERROR = "error"
57 CRITICAL = "critical"
58 ALERT = "alert"
59 EMERGENCY = "emergency"
62# Base content types
63class TextContent(BaseModel):
64 """Text content for messages.
66 Attributes:
67 type (Literal["text"]): The fixed content type identifier for text.
68 text (str): The actual text message.
69 """
71 type: Literal["text"]
72 text: str
75class JSONContent(BaseModel):
76 """JSON content for messages.
77 Attributes:
78 type (Literal["text"]): The fixed content type identifier for text.
79 json (dict): The actual text message.
80 """
82 type: Literal["text"]
83 text: dict
86class ImageContent(BaseModel):
87 """Image content for messages.
89 Attributes:
90 type (Literal["image"]): The fixed content type identifier for images.
91 data (bytes): The binary data of the image.
92 mime_type (str): The MIME type (e.g. "image/png") of the image.
93 """
95 type: Literal["image"]
96 data: bytes
97 mime_type: str
100class ResourceContent(BaseModel):
101 """Resource content that can be embedded.
103 Attributes:
104 type (Literal["resource"]): The fixed content type identifier for resources.
105 uri (str): The URI identifying the resource.
106 mime_type (Optional[str]): The MIME type of the resource, if known.
107 text (Optional[str]): A textual representation of the resource, if applicable.
108 blob (Optional[bytes]): Binary data of the resource, if applicable.
109 """
111 type: Literal["resource"]
112 uri: str
113 mime_type: Optional[str] = None
114 text: Optional[str] = None
115 blob: Optional[bytes] = None
118ContentType = Union[TextContent, JSONContent, ImageContent, ResourceContent]
121# Reference types - needed early for completion
122class PromptReference(BaseModel):
123 """Reference to a prompt or prompt template.
125 Attributes:
126 type (Literal["ref/prompt"]): The fixed reference type identifier for prompts.
127 name (str): The unique name of the prompt.
128 """
130 type: Literal["ref/prompt"]
131 name: str
134class ResourceReference(BaseModel):
135 """Reference to a resource or resource template.
137 Attributes:
138 type (Literal["ref/resource"]): The fixed reference type identifier for resources.
139 uri (str): The URI of the resource.
140 """
142 type: Literal["ref/resource"]
143 uri: str
146# Completion types
147class CompleteRequest(BaseModel):
148 """Request for completion suggestions.
150 Attributes:
151 ref (Union[PromptReference, ResourceReference]): A reference to a prompt or resource.
152 argument (Dict[str, str]): A dictionary containing arguments for the completion.
153 """
155 ref: Union[PromptReference, ResourceReference]
156 argument: Dict[str, str]
159class CompleteResult(BaseModel):
160 """Result for a completion request.
162 Attributes:
163 completion (Dict[str, Any]): A dictionary containing the completion results.
164 """
166 completion: Dict[str, Any] = Field(..., description="Completion results")
169# Implementation info
170class Implementation(BaseModel):
171 """MCP implementation information.
173 Attributes:
174 name (str): The name of the implementation.
175 version (str): The version of the implementation.
176 """
178 name: str
179 version: str
182# Model preferences
183class ModelHint(BaseModel):
184 """Hint for model selection.
186 Attributes:
187 name (Optional[str]): An optional hint for the model name.
188 """
190 name: Optional[str] = None
193class ModelPreferences(BaseModel):
194 """Server preferences for model selection.
196 Attributes:
197 cost_priority (float): Priority for cost efficiency (0 to 1).
198 speed_priority (float): Priority for speed (0 to 1).
199 intelligence_priority (float): Priority for intelligence (0 to 1).
200 hints (List[ModelHint]): A list of model hints.
201 """
203 cost_priority: float = Field(ge=0, le=1)
204 speed_priority: float = Field(ge=0, le=1)
205 intelligence_priority: float = Field(ge=0, le=1)
206 hints: List[ModelHint] = []
209# Capability types
210class ClientCapabilities(BaseModel):
211 """Capabilities that a client may support.
213 Attributes:
214 roots (Optional[Dict[str, bool]]): Capabilities related to root management.
215 sampling (Optional[Dict[str, Any]]): Capabilities related to LLM sampling.
216 experimental (Optional[Dict[str, Dict[str, Any]]]): Experimental capabilities.
217 """
219 roots: Optional[Dict[str, bool]] = None
220 sampling: Optional[Dict[str, Any]] = None
221 experimental: Optional[Dict[str, Dict[str, Any]]] = None
224class ServerCapabilities(BaseModel):
225 """Capabilities that a server may support.
227 Attributes:
228 prompts (Optional[Dict[str, bool]]): Capability for prompt support.
229 resources (Optional[Dict[str, bool]]): Capability for resource support.
230 tools (Optional[Dict[str, bool]]): Capability for tool support.
231 logging (Optional[Dict[str, Any]]): Capability for logging support.
232 experimental (Optional[Dict[str, Dict[str, Any]]]): Experimental capabilities.
233 """
235 prompts: Optional[Dict[str, bool]] = None
236 resources: Optional[Dict[str, bool]] = None
237 tools: Optional[Dict[str, bool]] = None
238 logging: Optional[Dict[str, Any]] = None
239 experimental: Optional[Dict[str, Dict[str, Any]]] = None
242# Initialization types
243class InitializeRequest(BaseModel):
244 """Initial request sent from the client to the server.
246 Attributes:
247 protocol_version (str): The protocol version (alias: protocolVersion).
248 capabilities (ClientCapabilities): The client's capabilities.
249 client_info (Implementation): The client's implementation information (alias: clientInfo).
251 Note:
252 The alias settings allow backward compatibility with older Pydantic versions.
253 """
255 protocol_version: str = Field(..., alias="protocolVersion")
256 capabilities: ClientCapabilities
257 client_info: Implementation = Field(..., alias="clientInfo")
259 class Config:
260 """Configuration for InitializeRequest.
262 Attributes:
263 populate_by_name (bool): Enables population by field name.
264 allow_population_by_field_name (bool): Allows backward compatibility with older Pydantic versions.
265 """
267 populate_by_name = True
268 allow_population_by_field_name = True # Use this for backward compatibility with older Pydantic versions
271class InitializeResult(BaseModel):
272 """Server's response to the initialization request.
274 Attributes:
275 protocol_version (str): The protocol version used.
276 capabilities (ServerCapabilities): The server's capabilities.
277 server_info (Implementation): The server's implementation information.
278 instructions (Optional[str]): Optional instructions for the client.
279 """
281 protocol_version: str = Field(..., alias="protocolVersion")
282 capabilities: ServerCapabilities = Field(..., alias="capabilities")
283 server_info: Implementation = Field(..., alias="serverInfo")
284 instructions: Optional[str] = Field(None, alias="instructions")
286 class Config:
287 """
288 Configuration class for Pydantic models.
290 Enables population of model fields by name and by field name.
291 """
293 populate_by_name = True
294 allow_population_by_field_name = True
297# Message types
298class Message(BaseModel):
299 """A message in a conversation.
301 Attributes:
302 role (Role): The role of the message sender.
303 content (ContentType): The content of the message.
304 """
306 role: Role
307 content: ContentType
310class SamplingMessage(BaseModel):
311 """A message used in LLM sampling requests.
313 Attributes:
314 role (Role): The role of the sender.
315 content (ContentType): The content of the sampling message.
316 """
318 role: Role
319 content: ContentType
322# Sampling types for the client features
323class CreateMessageResult(BaseModel):
324 """Result from a sampling/createMessage request.
326 Attributes:
327 content (Union[TextContent, ImageContent]): The generated content.
328 model (str): The model used for generating the content.
329 role (Role): The role associated with the content.
330 stop_reason (Optional[str]): An optional reason for why sampling stopped.
331 """
333 content: Union[TextContent, ImageContent]
334 model: str
335 role: Role
336 stop_reason: Optional[str] = None
339# Prompt types
340class PromptArgument(BaseModel):
341 """An argument that can be passed to a prompt.
343 Attributes:
344 name (str): The name of the argument.
345 description (Optional[str]): An optional description of the argument.
346 required (bool): Whether the argument is required. Defaults to False.
347 """
349 name: str
350 description: Optional[str] = None
351 required: bool = False
354class Prompt(BaseModel):
355 """A prompt template offered by the server.
357 Attributes:
358 name (str): The unique name of the prompt.
359 description (Optional[str]): A description of the prompt.
360 arguments (List[PromptArgument]): A list of expected prompt arguments.
361 """
363 name: str
364 description: Optional[str] = None
365 arguments: List[PromptArgument] = []
368class PromptResult(BaseModel):
369 """Result of rendering a prompt template.
371 Attributes:
372 messages (List[Message]): The list of messages produced by rendering the prompt.
373 description (Optional[str]): An optional description of the rendered result.
374 """
376 messages: List[Message]
377 description: Optional[str] = None
380# Tool types
381class Tool(BaseModel):
382 """A tool that can be invoked.
384 Attributes:
385 name (str): The unique name of the tool.
386 url (AnyHttpUrl): The URL of the tool.
387 description (Optional[str]): A description of the tool.
388 integrationType (str): The integration type of the tool (e.g. MCP or REST).
389 requestType (str): The HTTP method used to invoke the tool (GET, POST, PUT, DELETE, SSE, STDIO).
390 headers (Dict[str, Any]): A JSON object representing HTTP headers.
391 input_schema (Dict[str, Any]): A JSON Schema for validating the tool's input.
392 auth_type (Optional[str]): The type of authentication used ("basic", "bearer", or None).
393 auth_username (Optional[str]): The username for basic authentication.
394 auth_password (Optional[str]): The password for basic authentication.
395 auth_token (Optional[str]): The token for bearer authentication.
396 """
398 name: str
399 url: AnyHttpUrl
400 description: Optional[str] = None
401 integrationType: str = "MCP"
402 requestType: str = "SSE"
403 headers: Dict[str, Any] = Field(default_factory=dict)
404 input_schema: Dict[str, Any] = Field(default_factory=lambda: {"type": "object", "properties": {}})
405 auth_type: Optional[str] = None
406 auth_username: Optional[str] = None
407 auth_password: Optional[str] = None
408 auth_token: Optional[str] = None
411class ToolResult(BaseModel):
412 """Result of a tool invocation.
414 Attributes:
415 content (List[ContentType]): A list of content items returned by the tool.
416 is_error (bool): Flag indicating if the tool call resulted in an error.
417 """
419 content: List[ContentType]
420 is_error: bool = False
423# Resource types
424class Resource(BaseModel):
425 """A resource available from the server.
427 Attributes:
428 uri (str): The unique URI of the resource.
429 name (str): The human-readable name of the resource.
430 description (Optional[str]): A description of the resource.
431 mime_type (Optional[str]): The MIME type of the resource.
432 size (Optional[int]): The size of the resource.
433 """
435 uri: str
436 name: str
437 description: Optional[str] = None
438 mime_type: Optional[str] = None
439 size: Optional[int] = None
442class ResourceTemplate(BaseModel):
443 """A template for constructing resource URIs.
445 Attributes:
446 uri_template (str): The URI template string.
447 name (str): The unique name of the template.
448 description (Optional[str]): A description of the template.
449 mime_type (Optional[str]): The MIME type associated with the template.
450 """
452 uri_template: str
453 name: str
454 description: Optional[str] = None
455 mime_type: Optional[str] = None
458class ListResourceTemplatesResult(BaseModel):
459 """The server's response to a resources/templates/list request from the client.
461 Attributes:
462 meta (Optional[Dict[str, Any]]): Reserved property for metadata.
463 next_cursor (Optional[str]): Pagination cursor for the next page of results.
464 resource_templates (List[ResourceTemplate]): List of resource templates.
465 """
467 meta: Optional[Dict[str, Any]] = Field(
468 None, alias="_meta", description="This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses."
469 )
470 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.")
471 resource_templates: List[ResourceTemplate] = Field(default_factory=list, description="List of resource templates available on the server")
473 class Config:
474 """Configuration for model serialization."""
476 populate_by_name = True
477 allow_population_by_field_name = True
480# Root types
481class FileUrl(AnyUrl):
482 """A specialized URL type for local file-scheme resources.
484 Key characteristics
485 -------------------
486 * Scheme restricted – only the "file" scheme is permitted
487 (e.g. file:///path/to/file.txt).
488 * No host required – "file" URLs typically omit a network host;
489 therefore, the host component is not mandatory.
490 * String-friendly equality – developers naturally expect
491 FileUrl("file:///data") == "file:///data" to evaluate True.
492 AnyUrl (Pydantic) does not implement that, so we override
493 __eq__ to compare against plain strings transparently.
494 Hash semantics are kept consistent by delegating to the parent class.
496 Examples
497 --------
498 >>> url = FileUrl("file:///etc/hosts")
499 >>> url.scheme
500 'file'
501 >>> url == "file:///etc/hosts"
502 True
503 >>> {"path": url} # hashable
504 {'path': FileUrl('file:///etc/hosts')}
506 Notes
507 -----
508 The override does not interfere with comparisons to other
509 AnyUrl/FileUrl instances; those still use the superclass
510 implementation.
511 """
513 # Restrict to the "file" scheme and omit host requirement
514 allowed_schemes = {"file"}
515 host_required = False
517 def __eq__(self, other): # type: ignore[override]
518 """Return True when other is an equivalent URL or string.
520 If other is a str it is coerced with str(self) for comparison;
521 otherwise defer to AnyUrl's comparison.
523 Args:
524 other (Any): The object to compare against. May be a str, FileUrl, or AnyUrl.
526 Returns:
527 bool: True if the other value is equal to this URL, either as a string
528 or as another URL object. False otherwise.
529 """
530 if isinstance(other, str): 530 ↛ 532line 530 didn't jump to line 532 because the condition on line 530 was always true
531 return str(self) == other
532 return super().__eq__(other)
534 # Keep hashing behaviour aligned with equality
535 __hash__ = AnyUrl.__hash__
538class Root(BaseModel):
539 """A root directory or file.
541 Attributes:
542 uri (Union[FileUrl, AnyUrl]): The unique identifier for the root.
543 name (Optional[str]): An optional human-readable name.
544 """
546 uri: Union[FileUrl, AnyUrl] = Field(..., description="Unique identifier for the root")
547 name: Optional[str] = Field(None, description="Optional human-readable name")
550# Progress types
551class ProgressToken(BaseModel):
552 """Token for associating progress notifications.
554 Attributes:
555 value (Union[str, int]): The token value.
556 """
558 value: Union[str, int]
561class Progress(BaseModel):
562 """Progress update for long-running operations.
564 Attributes:
565 progress_token (ProgressToken): The token associated with the progress update.
566 progress (float): The current progress value.
567 total (Optional[float]): The total progress value, if known.
568 """
570 progress_token: ProgressToken
571 progress: float
572 total: Optional[float] = None
575# JSON-RPC types
576class JSONRPCRequest(BaseModel):
577 """JSON-RPC 2.0 request.
579 Attributes:
580 jsonrpc (Literal["2.0"]): The JSON-RPC version.
581 id (Optional[Union[str, int]]): The request identifier.
582 method (str): The method name.
583 params (Optional[Dict[str, Any]]): The parameters for the request.
584 """
586 jsonrpc: Literal["2.0"]
587 id: Optional[Union[str, int]] = None
588 method: str
589 params: Optional[Dict[str, Any]] = None
592class JSONRPCResponse(BaseModel):
593 """JSON-RPC 2.0 response.
595 Attributes:
596 jsonrpc (Literal["2.0"]): The JSON-RPC version.
597 id (Optional[Union[str, int]]): The request identifier.
598 result (Optional[Any]): The result of the request.
599 error (Optional[Dict[str, Any]]): The error object if an error occurred.
600 """
602 jsonrpc: Literal["2.0"]
603 id: Optional[Union[str, int]] = None
604 result: Optional[Any] = None
605 error: Optional[Dict[str, Any]] = None
608class JSONRPCError(BaseModel):
609 """JSON-RPC 2.0 error.
611 Attributes:
612 code (int): The error code.
613 message (str): A short description of the error.
614 data (Optional[Any]): Additional data about the error.
615 """
617 code: int
618 message: str
619 data: Optional[Any] = None
622# Transport message types
623class SSEEvent(BaseModel):
624 """Server-Sent Events message.
626 Attributes:
627 id (Optional[str]): The event identifier.
628 event (Optional[str]): The event type.
629 data (str): The event data.
630 retry (Optional[int]): The retry timeout in milliseconds.
631 """
633 id: Optional[str] = None
634 event: Optional[str] = None
635 data: str
636 retry: Optional[int] = None
639class WebSocketMessage(BaseModel):
640 """WebSocket protocol message.
642 Attributes:
643 type (str): The type of the WebSocket message.
644 data (Any): The message data.
645 """
647 type: str
648 data: Any
651# Notification types
652class ResourceUpdateNotification(BaseModel):
653 """Notification of resource changes.
655 Attributes:
656 method (Literal["notifications/resources/updated"]): The notification method.
657 uri (str): The URI of the updated resource.
658 """
660 method: Literal["notifications/resources/updated"]
661 uri: str
664class ResourceListChangedNotification(BaseModel):
665 """Notification of resource list changes.
667 Attributes:
668 method (Literal["notifications/resources/list_changed"]): The notification method.
669 """
671 method: Literal["notifications/resources/list_changed"]
674class PromptListChangedNotification(BaseModel):
675 """Notification of prompt list changes.
677 Attributes:
678 method (Literal["notifications/prompts/list_changed"]): The notification method.
679 """
681 method: Literal["notifications/prompts/list_changed"]
684class ToolListChangedNotification(BaseModel):
685 """Notification of tool list changes.
687 Attributes:
688 method (Literal["notifications/tools/list_changed"]): The notification method.
689 """
691 method: Literal["notifications/tools/list_changed"]
694class CancelledNotification(BaseModel):
695 """Notification of request cancellation.
697 Attributes:
698 method (Literal["notifications/cancelled"]): The notification method.
699 request_id (Union[str, int]): The ID of the cancelled request.
700 reason (Optional[str]): An optional reason for cancellation.
701 """
703 method: Literal["notifications/cancelled"]
704 request_id: Union[str, int]
705 reason: Optional[str] = None
708class ProgressNotification(BaseModel):
709 """Notification of operation progress.
711 Attributes:
712 method (Literal["notifications/progress"]): The notification method.
713 progress_token (ProgressToken): The token associated with the progress.
714 progress (float): The current progress value.
715 total (Optional[float]): The total progress value, if known.
716 """
718 method: Literal["notifications/progress"]
719 progress_token: ProgressToken
720 progress: float
721 total: Optional[float] = None
724class LoggingNotification(BaseModel):
725 """Notification of log messages.
727 Attributes:
728 method (Literal["notifications/message"]): The notification method.
729 level (LogLevel): The log level of the message.
730 logger (Optional[str]): The logger name.
731 data (Any): The log message data.
732 """
734 method: Literal["notifications/message"]
735 level: LogLevel
736 logger: Optional[str] = None
737 data: Any
740# Federation types
741class FederatedTool(Tool):
742 """A tool from a federated gateway.
744 Attributes:
745 gateway_id (str): The identifier of the gateway.
746 gateway_name (str): The name of the gateway.
747 """
749 gateway_id: str
750 gateway_name: str
753class FederatedResource(Resource):
754 """A resource from a federated gateway.
756 Attributes:
757 gateway_id (str): The identifier of the gateway.
758 gateway_name (str): The name of the gateway.
759 """
761 gateway_id: str
762 gateway_name: str
765class FederatedPrompt(Prompt):
766 """A prompt from a federated gateway.
768 Attributes:
769 gateway_id (str): The identifier of the gateway.
770 gateway_name (str): The name of the gateway.
771 """
773 gateway_id: str
774 gateway_name: str
777class Gateway(BaseModel):
778 """A federated gateway peer.
780 Attributes:
781 id (str): The unique identifier for the gateway.
782 name (str): The name of the gateway.
783 url (AnyHttpUrl): The URL of the gateway.
784 capabilities (ServerCapabilities): The capabilities of the gateway.
785 last_seen (Optional[datetime]): Timestamp when the gateway was last seen.
786 """
788 id: str
789 name: str
790 url: AnyHttpUrl
791 capabilities: ServerCapabilities
792 last_seen: Optional[datetime] = None