Skip to content

Commit ff63eaa

Browse files
committed
[minimcp] Add exception hierarchy and message types
- Define external errors (MiniMCPError and subclasses) - Define internal errors (InternalMCPError and subclasses) - Define special tool errors (SpecialToolError hierarchy) - Define message handling types (Message, NoMessage, Send)
1 parent 0dedbd9 commit ff63eaa

File tree

2 files changed

+174
-0
lines changed

2 files changed

+174
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from typing import Any
2+
3+
from mcp.server.minimcp.types import Message
4+
5+
# --- External Errors ---------------------------------------------
6+
7+
8+
class MiniMCPError(Exception):
9+
"""
10+
Base for all MiniMCP errors that would be exposed externally.
11+
"""
12+
13+
pass
14+
15+
16+
class MiniMCPJSONRPCError(MiniMCPError):
17+
"""
18+
Base exception for all MiniMCP errors with a MCP response message.
19+
They must be handled by the transport layer to be returned to the client.
20+
"""
21+
22+
response: Message
23+
24+
def __init__(self, error_message: str, response: Message):
25+
super().__init__(error_message)
26+
self.response = response
27+
28+
29+
class InvalidMessageError(MiniMCPJSONRPCError):
30+
"""Invalid message error - The message is not a valid JSON-RPC message."""
31+
32+
pass
33+
34+
35+
class ContextError(MiniMCPError):
36+
"""
37+
Context error - Raised when when context access fails. Can be caused by:
38+
- No Context: Called get outside of an active context.
39+
- Scope is not available in current context.
40+
- Responder is not available in current context.
41+
"""
42+
43+
pass
44+
45+
46+
class MCPFuncError(MiniMCPError):
47+
"""Raised when an error occurs inside an MCP function."""
48+
49+
pass
50+
51+
52+
class PrimitiveError(MiniMCPError):
53+
"""
54+
Raised when an error is encountered while adding, retrieving
55+
or removing a primitive (prompt, resource, tool)
56+
"""
57+
58+
pass
59+
60+
61+
# --- Internal Errors ---------------------------------------------
62+
63+
64+
class InternalMCPError(Exception):
65+
"""
66+
These errors are raised and managed by MiniMCP internally,
67+
and are not expected to be exposed externally - Neither inside the handlers nor the transport layer.
68+
"""
69+
70+
data: dict[str, Any] | None = None
71+
72+
def __init__(self, message: str, data: dict[str, Any] | None = None):
73+
super().__init__(message, data)
74+
self.data = data
75+
76+
77+
class InvalidJSONError(InternalMCPError):
78+
"""Raised when the message is not a valid JSON string."""
79+
80+
pass
81+
82+
83+
class InvalidJSONRPCMessageError(InternalMCPError):
84+
"""Raised when the message is not valid JSON-RPC object."""
85+
86+
pass
87+
88+
89+
class InvalidMCPMessageError(InternalMCPError):
90+
"""Raised when the message is not a valid MCP message."""
91+
92+
pass
93+
94+
95+
class InvalidArgumentsError(InternalMCPError):
96+
"""Invalid arguments error - Caused by pydantic ValidationError."""
97+
98+
pass
99+
100+
101+
class UnsupportedMessageTypeError(InternalMCPError):
102+
"""
103+
Unsupported message type received
104+
MiniMCP expects the incoming message to be a JSONRPCRequest or JSONRPCNotification.
105+
"""
106+
107+
pass
108+
109+
110+
class RequestHandlerNotFoundError(InternalMCPError):
111+
"""
112+
The client request does not have a handler registered in the MiniMCP server.
113+
Handlers are registered per request type.
114+
Request types: PingRequest, InitializeRequest, CompleteRequest, SetLevelRequest,
115+
GetPromptRequest, ListPromptsRequest, ListResourcesRequest, ListResourceTemplatesRequest,
116+
ReadResourceRequest, SubscribeRequest, UnsubscribeRequest, CallToolRequest, ListToolsRequest
117+
"""
118+
119+
pass
120+
121+
122+
class ResourceNotFoundError(InternalMCPError):
123+
"""Resource not found error - Raised when a resource is not found."""
124+
125+
pass
126+
127+
128+
class MCPRuntimeError(InternalMCPError):
129+
"""MCP runtime error - Raised when a runtime error occurs."""
130+
131+
pass
132+
133+
134+
# --- Special Tool Errors ---------------------------------------------
135+
# These exceptions inherit from BaseException (not Exception) to bypass the low-level
136+
# server's default exception handler during tool execution. This allows the tool manager
137+
# to implement custom error handling and response formatting
138+
139+
140+
class SpecialToolError(BaseException):
141+
pass
142+
143+
144+
class ToolPrimitiveError(SpecialToolError):
145+
pass
146+
147+
148+
class ToolInvalidArgumentsError(SpecialToolError):
149+
pass
150+
151+
152+
class ToolMCPRuntimeError(SpecialToolError):
153+
pass

src/mcp/server/minimcp/types.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from collections.abc import Awaitable, Callable
2+
from enum import Enum
3+
from typing import Final, Literal
4+
5+
MESSAGE_ENCODING: Final[Literal["utf-8"]] = "utf-8"
6+
7+
# --- MCP response types ---
8+
Message = str
9+
10+
11+
class NoMessage(Enum):
12+
"""
13+
Represents handler responses without any message.
14+
https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#sending-messages-to-the-server
15+
"""
16+
17+
NOTIFICATION = "notification" # Response to a client notification
18+
19+
20+
# --- Message callback type ---
21+
Send = Callable[[Message], Awaitable[None]]

0 commit comments

Comments
 (0)