Model Context Protocol SDK for building MCP servers and clients in Python
—
Complete MCP protocol type definitions including requests, responses, notifications, capabilities, and data models. These types define the structure and behavior of the Model Context Protocol, enabling type-safe communication between clients and servers.
Core protocol version and error code constants.
LATEST_PROTOCOL_VERSION: str = "2025-06-18"
DEFAULT_NEGOTIATED_VERSION: str = "2025-03-26"
# JSON-RPC Error Codes
CONNECTION_CLOSED: int = -32000
PARSE_ERROR: int = -32700
INVALID_REQUEST: int = -32600
METHOD_NOT_FOUND: int = -32601
INVALID_PARAMS: int = -32602
INTERNAL_ERROR: int = -32603Common type aliases used throughout the protocol.
ProgressToken = str | int
Cursor = str
Role = Literal["user", "assistant"]
RequestId = int | strBase classes for JSON-RPC communication and MCP protocol structure.
class JSONRPCRequest(BaseModel):
"""Base JSON-RPC request."""
jsonrpc: str = "2.0"
id: RequestId
method: str
params: dict[str, Any] | None = None
class JSONRPCResponse(BaseModel):
"""Base JSON-RPC response."""
jsonrpc: str = "2.0"
id: RequestId
result: Any | None = None
error: JSONRPCError | None = None
class JSONRPCError(BaseModel):
"""JSON-RPC error object."""
code: int
message: str
data: Any | None = None
class Request(BaseModel):
"""Base MCP request."""
method: str
params: dict[str, Any] | None = None
class Notification(BaseModel):
"""Base MCP notification."""
method: str
params: dict[str, Any] | None = None
class ErrorData(BaseModel):
"""MCP error data structure."""
code: int
message: str
data: Any | None = None
class Implementation(BaseModel):
"""Client or server implementation metadata."""
name: str
version: str
class EmptyResult(BaseModel):
"""A response that indicates success but carries no data."""
passTypes for protocol initialization and capability negotiation.
class InitializeRequest(BaseModel):
"""Protocol initialization request."""
protocolVersion: str
capabilities: ClientCapabilities
clientInfo: Implementation
class InitializeResult(BaseModel):
"""Protocol initialization response."""
protocolVersion: str
capabilities: ServerCapabilities
serverInfo: Implementation
instructions: str | None = None
class InitializedNotification(BaseModel):
"""Protocol initialization completion notification."""
method: Literal["notifications/initialized"] = "notifications/initialized"
class ClientCapabilities(BaseModel):
"""Client capability declarations."""
experimental: dict[str, Any] | None = None
sampling: dict[str, Any] | None = None
roots: RootsCapability | None = None
class ServerCapabilities(BaseModel):
"""Server capability declarations."""
experimental: dict[str, Any] | None = None
logging: dict[str, Any] | None = None
prompts: PromptsCapability | None = None
resources: ResourcesCapability | None = None
tools: ToolsCapability | None = None
class PromptsCapability(BaseModel):
"""Prompts capability settings."""
listChanged: bool | None = None
class ResourcesCapability(BaseModel):
"""Resources capability settings."""
subscribe: bool | None = None
listChanged: bool | None = None
class ToolsCapability(BaseModel):
"""Tools capability settings."""
listChanged: bool | None = None
class RootsCapability(BaseModel):
"""Roots capability settings."""
listChanged: bool | None = NoneTypes for tool listing, execution, and management.
class Tool(BaseModel):
"""Tool definition."""
name: str
description: str | None = None
inputSchema: dict[str, Any]
class ListToolsRequest(BaseModel):
"""List available tools request."""
method: Literal["tools/list"] = "tools/list"
params: dict[str, Any] | None = None
class ListToolsResult(BaseModel):
"""List available tools response."""
tools: list[Tool]
nextCursor: str | None = None
class CallToolRequest(BaseModel):
"""Tool execution request."""
method: Literal["tools/call"] = "tools/call"
params: dict[str, Any]
class CallToolResult(BaseModel):
"""Tool execution response."""
content: list[ContentBlock]
isError: bool | None = NoneTypes for resource listing, reading, and subscription management.
class Resource(BaseModel):
"""Resource definition."""
uri: AnyUrl
name: str
description: str | None = None
mimeType: str | None = None
class ResourceTemplate(BaseModel):
"""Resource template with URI pattern."""
uriTemplate: str
name: str
description: str | None = None
mimeType: str | None = None
class ListResourcesRequest(BaseModel):
"""List available resources request."""
method: Literal["resources/list"] = "resources/list"
params: dict[str, Any] | None = None
class ListResourcesResult(BaseModel):
"""List available resources response."""
resources: list[Resource]
nextCursor: str | None = None
class ListResourceTemplatesResult(BaseModel):
"""List available resource templates response."""
resourceTemplates: list[ResourceTemplate]
nextCursor: str | None = None
class ReadResourceRequest(BaseModel):
"""Read resource content request."""
method: Literal["resources/read"] = "resources/read"
params: dict[str, Any]
class ReadResourceResult(BaseModel):
"""Read resource content response."""
contents: list[ContentBlock]
class SubscribeRequest(BaseModel):
"""Subscribe to resource updates request."""
method: Literal["resources/subscribe"] = "resources/subscribe"
params: dict[str, Any]
class UnsubscribeRequest(BaseModel):
"""Unsubscribe from resource updates request."""
method: Literal["resources/unsubscribe"] = "resources/unsubscribe"
params: dict[str, Any]
class ResourceUpdatedNotification(BaseModel):
"""Resource update notification."""
method: Literal["notifications/resources/updated"] = "notifications/resources/updated"
params: dict[str, Any]Types for different content formats and data structures.
class TextContent(BaseModel):
"""Text content block."""
type: Literal["text"] = "text"
text: str
class ImageContent(BaseModel):
"""Image content block."""
type: Literal["image"] = "image"
data: str # Base64 encoded image data
mimeType: str
class AudioContent(BaseModel):
"""Audio content block."""
type: Literal["audio"] = "audio"
data: str # Base64 encoded audio data
mimeType: str
class EmbeddedResource(BaseModel):
"""Embedded resource content."""
type: Literal["resource"] = "resource"
resource: ResourceContents
class ResourceLink(BaseModel):
"""Resource link reference."""
type: Literal["resource"] = "resource"
uri: AnyUrl
class ResourceContents(BaseModel):
"""Resource content wrapper."""
uri: AnyUrl
mimeType: str | None = None
text: str | None = None
blob: str | None = None # Base64 encoded binary data
ContentBlock = TextContent | ImageContent | AudioContent | EmbeddedResource | ResourceLinkTypes for prompt templates, retrieval, and message handling.
class Prompt(BaseModel):
"""Prompt template definition."""
name: str
description: str | None = None
arguments: list[PromptArgument] | None = None
class PromptArgument(BaseModel):
"""Prompt template argument."""
name: str
description: str | None = None
required: bool | None = None
class ListPromptsRequest(BaseModel):
"""List available prompts request."""
method: Literal["prompts/list"] = "prompts/list"
params: dict[str, Any] | None = None
class ListPromptsResult(BaseModel):
"""List available prompts response."""
prompts: list[Prompt]
nextCursor: str | None = None
class GetPromptRequest(BaseModel):
"""Get prompt content request."""
method: Literal["prompts/get"] = "prompts/get"
params: dict[str, Any]
class GetPromptResult(BaseModel):
"""Get prompt content response."""
description: str | None = None
messages: list[PromptMessage]
class PromptMessage(BaseModel):
"""Prompt message with role and content."""
role: Role
content: ContentBlockTypes for progress tracking and server notifications.
class ProgressNotification(BaseModel):
"""Progress update notification."""
method: Literal["notifications/progress"] = "notifications/progress"
params: ProgressNotificationParams
class ProgressNotificationParams(BaseModel):
"""Progress notification parameters."""
progressToken: ProgressToken
progress: float
total: float | None = None
class LoggingMessageNotification(BaseModel):
"""Logging message notification."""
method: Literal["notifications/message"] = "notifications/message"
params: dict[str, Any]
class LoggingLevel(str, Enum):
"""Logging level enumeration."""
DEBUG = "debug"
INFO = "info"
NOTICE = "notice"
WARNING = "warning"
ERROR = "error"
CRITICAL = "critical"
ALERT = "alert"
EMERGENCY = "emergency"
class SetLevelRequest(BaseModel):
"""Set logging level request."""
method: Literal["logging/setLevel"] = "logging/setLevel"
params: dict[str, Any]Types for LLM sampling requests and message creation.
class CreateMessageRequest(BaseModel):
"""Create LLM message request."""
method: Literal["sampling/createMessage"] = "sampling/createMessage"
params: dict[str, Any]
class CreateMessageResult(BaseModel):
"""Create LLM message response."""
role: Role
content: ContentBlock
model: str
stopReason: StopReason | None = None
class SamplingMessage(BaseModel):
"""Message for LLM sampling."""
role: Role
content: ContentBlock
class ModelPreferences(BaseModel):
"""LLM model preferences."""
hints: list[ModelHint] | None = None
costPriority: float | None = None
speedPriority: float | None = None
intelligencePriority: float | None = None
class ModelHint(BaseModel):
"""LLM model hint."""
name: str | None = None
class StopReason(str, Enum):
"""Sampling stop reason."""
endTurn = "endTurn"
stopSequence = "stopSequence"
maxTokens = "maxTokens"Types for completion suggestions and text completions.
class CompleteRequest(BaseModel):
"""Completion request."""
method: Literal["completion/complete"] = "completion/complete"
params: dict[str, Any]
class CompleteResult(BaseModel):
"""Completion response."""
completion: Completion
class Completion(BaseModel):
"""Completion suggestion."""
values: list[str]
total: int | None = None
hasMore: bool | None = None
class CompletionArgument(BaseModel):
"""Completion argument context."""
name: str
value: str
class CompletionReference(BaseModel):
"""Reference for completion requests."""
type: str # "resource" or "prompt"
uri: str | None = None
name: str | None = NoneUnion types for protocol messages and results.
# Client-side unions
ClientRequest = (
InitializeRequest |
ListToolsRequest |
CallToolRequest |
ListResourcesRequest |
ReadResourceRequest |
SubscribeRequest |
UnsubscribeRequest |
ListPromptsRequest |
GetPromptRequest |
SetLevelRequest |
CompleteRequest
)
ClientResult = (
InitializeResult |
ListToolsResult |
CallToolResult |
ListResourcesResult |
ReadResourceResult |
ListPromptsResult |
GetPromptResult |
CompleteResult
)
ClientNotification = (
InitializedNotification |
ProgressNotification |
LoggingMessageNotification
)
# Server-side unions
ServerRequest = CreateMessageRequest
ServerResult = CreateMessageResult
ServerNotification = ResourceUpdatedNotificationException classes for MCP protocol errors.
class McpError(Exception):
"""MCP protocol exception."""
def __init__(
self,
message: str,
code: int = INTERNAL_ERROR,
data: Any | None = None
):
"""
Initialize MCP error.
Parameters:
- message: Error message
- code: Error code (JSON-RPC error code)
- data: Additional error data
"""
super().__init__(message)
self.code = code
self.data = data
def to_error_data(self) -> ErrorData:
"""Convert to ErrorData structure."""
return ErrorData(
code=self.code,
message=str(self),
data=self.data
)from mcp import Tool, CallToolResult, TextContent
from pydantic import BaseModel
# Define tool input schema using Pydantic
class CalculatorInput(BaseModel):
operation: str
a: float
b: float
# Create tool with proper typing
calculator_tool = Tool(
name="calculator",
description="Perform basic math operations",
inputSchema=CalculatorInput.model_json_schema()
)
# Type-safe tool handler
async def handle_calculator(name: str, arguments: dict) -> CallToolResult:
# Validate input using Pydantic
input_data = CalculatorInput.model_validate(arguments)
# Perform calculation
if input_data.operation == "add":
result = input_data.a + input_data.b
elif input_data.operation == "multiply":
result = input_data.a * input_data.b
else:
raise ValueError(f"Unknown operation: {input_data.operation}")
# Return typed result
return CallToolResult(
content=[TextContent(type="text", text=str(result))]
)from mcp import ContentBlock, BaseModel
from typing import Literal
# Define custom content type
class ChartContent(BaseModel):
"""Custom chart content type."""
type: Literal["chart"] = "chart"
chart_type: str # "bar", "line", "pie", etc.
data: dict[str, Any]
options: dict[str, Any] | None = None
# Use in tool responses
async def generate_chart() -> list[ContentBlock]:
chart = ChartContent(
chart_type="bar",
data={
"labels": ["A", "B", "C"],
"values": [10, 20, 15]
},
options={"title": "Sample Chart"}
)
return [chart]Install with Tessl CLI
npx tessl i tessl/pypi-mcp