18
18
from strands .types .tools import ToolUse
19
19
20
20
21
- def start_calculator_server (transport : Literal ["sse" , "streamable-http" ], port = int ):
21
+ def start_comprehensive_mcp_server (transport : Literal ["sse" , "streamable-http" ], port = int ):
22
22
"""
23
- Initialize and start an MCP calculator server for integration testing.
23
+ Initialize and start a comprehensive MCP server for integration testing.
24
24
25
- This function creates a FastMCP server instance that provides a simple
26
- calculator tool for performing addition operations. The server uses
27
- Server-Sent Events (SSE) transport for communication, making it accessible
28
- over HTTP.
25
+ This function creates a FastMCP server instance that provides tools, prompts,
26
+ and resources all in one server for comprehensive testing. The server uses
27
+ Server-Sent Events (SSE) or streamable HTTP transport for communication.
29
28
"""
30
29
from mcp .server import FastMCP
31
30
32
- mcp = FastMCP ("Calculator Server" , port = port )
31
+ mcp = FastMCP ("Comprehensive MCP Server" , port = port )
33
32
34
33
@mcp .tool (description = "Calculator tool which performs calculations" )
35
34
def calculator (x : int , y : int ) -> int :
@@ -44,6 +43,15 @@ def generate_custom_image() -> MCPImageContent:
44
43
except Exception as e :
45
44
print ("Error while generating custom image: {}" .format (e ))
46
45
46
+ # Prompts
47
+ @mcp .prompt (description = "A greeting prompt template" )
48
+ def greeting_prompt (name : str = "World" ) -> str :
49
+ return f"Hello, { name } ! How are you today?"
50
+
51
+ @mcp .prompt (description = "A math problem prompt template" )
52
+ def math_prompt (operation : str = "addition" , difficulty : str = "easy" ) -> str :
53
+ return f"Create a { difficulty } { operation } math problem and solve it step by step."
54
+
47
55
mcp .run (transport = transport )
48
56
49
57
@@ -58,8 +66,9 @@ def test_mcp_client():
58
66
{'role': 'assistant', 'content': [{'text': '\n \n The result of adding 1 and 2 is 3.'}]}
59
67
""" # noqa: E501
60
68
69
+ # Start comprehensive server with tools, prompts, and resources
61
70
server_thread = threading .Thread (
62
- target = start_calculator_server , kwargs = {"transport" : "sse" , "port" : 8000 }, daemon = True
71
+ target = start_comprehensive_mcp_server , kwargs = {"transport" : "sse" , "port" : 8000 }, daemon = True
63
72
)
64
73
server_thread .start ()
65
74
time .sleep (2 ) # wait for server to startup completely
@@ -68,8 +77,14 @@ def test_mcp_client():
68
77
stdio_mcp_client = MCPClient (
69
78
lambda : stdio_client (StdioServerParameters (command = "python" , args = ["tests_integ/echo_server.py" ]))
70
79
)
80
+
71
81
with sse_mcp_client , stdio_mcp_client :
72
- agent = Agent (tools = sse_mcp_client .list_tools_sync () + stdio_mcp_client .list_tools_sync ())
82
+ # Test Tools functionality
83
+ sse_tools = sse_mcp_client .list_tools_sync ()
84
+ stdio_tools = stdio_mcp_client .list_tools_sync ()
85
+ all_tools = sse_tools + stdio_tools
86
+
87
+ agent = Agent (tools = all_tools )
73
88
agent ("add 1 and 2, then echo the result back to me" )
74
89
75
90
tool_use_content_blocks = _messages_to_content_blocks (agent .messages )
@@ -88,6 +103,43 @@ def test_mcp_client():
88
103
]
89
104
)
90
105
106
+ # Test Prompts functionality
107
+ prompts_result = sse_mcp_client .list_prompts_sync ()
108
+ assert len (prompts_result .prompts ) >= 2 # We expect at least greeting and math prompts
109
+
110
+ prompt_names = [prompt .name for prompt in prompts_result .prompts ]
111
+ assert "greeting_prompt" in prompt_names
112
+ assert "math_prompt" in prompt_names
113
+
114
+ # Test get_prompt_sync with greeting prompt
115
+ greeting_result = sse_mcp_client .get_prompt_sync ("greeting_prompt" , {"name" : "Alice" })
116
+ assert len (greeting_result .messages ) > 0
117
+ prompt_text = greeting_result .messages [0 ].content .text
118
+ assert "Hello, Alice!" in prompt_text
119
+ assert "How are you today?" in prompt_text
120
+
121
+ # Test get_prompt_sync with math prompt
122
+ math_result = sse_mcp_client .get_prompt_sync (
123
+ "math_prompt" , {"operation" : "multiplication" , "difficulty" : "medium" }
124
+ )
125
+ assert len (math_result .messages ) > 0
126
+ math_text = math_result .messages [0 ].content .text
127
+ assert "multiplication" in math_text
128
+ assert "medium" in math_text
129
+ assert "step by step" in math_text
130
+
131
+ # Test pagination support for prompts
132
+ prompts_with_token = sse_mcp_client .list_prompts_sync (pagination_token = None )
133
+ assert len (prompts_with_token .prompts ) >= 0
134
+
135
+ # Test pagination support for tools (existing functionality)
136
+ tools_with_token = sse_mcp_client .list_tools_sync (pagination_token = None )
137
+ assert len (tools_with_token ) >= 0
138
+
139
+ # TODO: Add resources testing when resources are implemented
140
+ # resources_result = sse_mcp_client.list_resources_sync()
141
+ # assert len(resources_result.resources) >= 0
142
+
91
143
tool_use_id = "test-structured-content-123"
92
144
result = stdio_mcp_client .call_tool_sync (
93
145
tool_use_id = tool_use_id ,
@@ -185,8 +237,9 @@ def test_mcp_client_without_structured_content():
185
237
reason = "streamable transport is failing in GitHub actions, debugging if linux compatibility issue" ,
186
238
)
187
239
def test_streamable_http_mcp_client ():
240
+ """Test comprehensive MCP client with streamable HTTP transport."""
188
241
server_thread = threading .Thread (
189
- target = start_calculator_server , kwargs = {"transport" : "streamable-http" , "port" : 8001 }, daemon = True
242
+ target = start_comprehensive_mcp_server , kwargs = {"transport" : "streamable-http" , "port" : 8001 }, daemon = True
190
243
)
191
244
server_thread .start ()
192
245
time .sleep (2 ) # wait for server to startup completely
@@ -196,12 +249,22 @@ def transport_callback() -> MCPTransport:
196
249
197
250
streamable_http_client = MCPClient (transport_callback )
198
251
with streamable_http_client :
252
+ # Test tools
199
253
agent = Agent (tools = streamable_http_client .list_tools_sync ())
200
254
agent ("add 1 and 2 using a calculator" )
201
255
202
256
tool_use_content_blocks = _messages_to_content_blocks (agent .messages )
203
257
assert any ([block ["name" ] == "calculator" for block in tool_use_content_blocks ])
204
258
259
+ # Test prompts
260
+ prompts_result = streamable_http_client .list_prompts_sync ()
261
+ assert len (prompts_result .prompts ) >= 2
262
+
263
+ greeting_result = streamable_http_client .get_prompt_sync ("greeting_prompt" , {"name" : "Charlie" })
264
+ assert len (greeting_result .messages ) > 0
265
+ prompt_text = greeting_result .messages [0 ].content .text
266
+ assert "Hello, Charlie!" in prompt_text
267
+
205
268
206
269
def _messages_to_content_blocks (messages : List [Message ]) -> List [ToolUse ]:
207
270
return [block ["toolUse" ] for message in messages for block in message ["content" ] if "toolUse" in block ]
0 commit comments