1
1
# Copyright (c) Microsoft. All rights reserved.
2
- import os
3
2
from typing import TYPE_CHECKING
4
3
from unittest .mock import MagicMock , patch
5
4
6
5
import pytest
7
- from mcp import ClientSession , StdioServerParameters
6
+ from mcp import ClientSession , ListToolsResult , StdioServerParameters , Tool
8
7
9
8
from semantic_kernel .connectors .mcp import (
10
9
MCPSseServerConfig ,
11
10
MCPStdioServerConfig ,
12
11
create_plugin_from_mcp_server ,
13
12
)
14
13
from semantic_kernel .exceptions import KernelPluginInvalidConfigurationError
15
- from semantic_kernel .functions import KernelArguments
16
14
17
15
if TYPE_CHECKING :
18
- from semantic_kernel import Kernel
16
+ pass
19
17
20
18
21
19
async def test_mcp_server_config_session_initialize ():
@@ -104,34 +102,6 @@ async def test_mcp_stdio_server_config_failed_get_session():
104
102
pass
105
103
106
104
107
- async def test_from_mcp (kernel : "Kernel" ):
108
- mcp_server_path = os .path .join (os .path .dirname (__file__ ), "../../../assets/test_plugins" , "TestMCPPlugin" )
109
- mcp_server_file = "mcp_server.py"
110
- config = MCPStdioServerConfig (
111
- command = "uv" ,
112
- args = ["--directory" , mcp_server_path , "run" , mcp_server_file ],
113
- )
114
-
115
- plugin = await create_plugin_from_mcp_server (
116
- plugin_name = "TestMCPPlugin" ,
117
- description = "Test MCP Plugin" ,
118
- server_config = config ,
119
- )
120
-
121
- assert plugin is not None
122
- assert plugin .name == "TestMCPPlugin"
123
- assert plugin .functions .get ("get_name" ) is not None
124
- assert plugin .functions ["get_name" ].parameters [0 ].name == "name"
125
- assert plugin .functions ["get_name" ].parameters [0 ].type_ == "string"
126
- assert plugin .functions ["get_name" ].parameters [0 ].is_required
127
- assert plugin .functions .get ("set_name" ) is not None
128
-
129
- kernel .add_plugin (plugin )
130
-
131
- result = await plugin .functions ["get_name" ].invoke (kernel , arguments = KernelArguments (name = "test" ))
132
- assert "test: Test" in result .value
133
-
134
-
135
105
@patch ("semantic_kernel.connectors.mcp.stdio_client" )
136
106
@patch ("semantic_kernel.connectors.mcp.ClientSession" )
137
107
async def test_with_kwargs_stdio (mock_session , mock_client ):
@@ -145,7 +115,21 @@ async def test_with_kwargs_stdio(mock_session, mock_client):
145
115
146
116
# Make the mock_stdio_client return an AsyncMock for the context manager
147
117
mock_client .return_value = mock_generator
148
- await create_plugin_from_mcp_server (
118
+ mock_session .return_value .__aenter__ .return_value .list_tools .return_value = ListToolsResult (
119
+ tools = [
120
+ Tool (
121
+ name = "get_name" ,
122
+ description = "Get Name" ,
123
+ inputSchema = {
124
+ "properties" : {
125
+ "name" : {"type" : "string" },
126
+ },
127
+ "required" : ["name" ],
128
+ },
129
+ )
130
+ ]
131
+ )
132
+ plugin = await create_plugin_from_mcp_server (
149
133
plugin_name = "TestMCPPlugin" ,
150
134
description = "Test MCP Plugin" ,
151
135
command = "uv" ,
@@ -154,6 +138,12 @@ async def test_with_kwargs_stdio(mock_session, mock_client):
154
138
mock_client .assert_called_once_with (
155
139
server = StdioServerParameters (command = "uv" , args = ["--directory" , "path" , "run" , "file.py" ])
156
140
)
141
+ assert plugin is not None
142
+ assert plugin .name == "TestMCPPlugin"
143
+ assert plugin .description == "Test MCP Plugin"
144
+ assert plugin .functions .get ("get_name" ) is not None
145
+ assert plugin .functions ["get_name" ].parameters [0 ].name == "name"
146
+ assert plugin .functions ["get_name" ].parameters [0 ].is_required
157
147
158
148
159
149
@patch ("semantic_kernel.connectors.mcp.sse_client" )
@@ -169,9 +159,29 @@ async def test_with_kwargs_sse(mock_session, mock_client):
169
159
170
160
# Make the mock_stdio_client return an AsyncMock for the context manager
171
161
mock_client .return_value = mock_generator
172
- await create_plugin_from_mcp_server (
162
+ mock_session .return_value .__aenter__ .return_value .list_tools .return_value = ListToolsResult (
163
+ tools = [
164
+ Tool (
165
+ name = "get_name" ,
166
+ description = "Get Name" ,
167
+ inputSchema = {
168
+ "properties" : {
169
+ "name" : {"type" : "string" },
170
+ },
171
+ "required" : ["name" ],
172
+ },
173
+ )
174
+ ]
175
+ )
176
+ plugin = await create_plugin_from_mcp_server (
173
177
plugin_name = "TestMCPPlugin" ,
174
178
description = "Test MCP Plugin" ,
175
179
url = "http://localhost:8080/sse" ,
176
180
)
177
181
mock_client .assert_called_once_with (url = "http://localhost:8080/sse" )
182
+ assert plugin is not None
183
+ assert plugin .name == "TestMCPPlugin"
184
+ assert plugin .description == "Test MCP Plugin"
185
+ assert plugin .functions .get ("get_name" ) is not None
186
+ assert plugin .functions ["get_name" ].parameters [0 ].name == "name"
187
+ assert plugin .functions ["get_name" ].parameters [0 ].is_required
0 commit comments