@@ -51,44 +51,48 @@ vi.mock('@modelcontextprotocol/sdk/client/stdio.js', async () => {
51
51
} ) ) }
52
52
} )
53
53
54
+ let count = 1
54
55
vi . mock ( '@modelcontextprotocol/sdk/client/index.js' , async ( ) => {
55
- const Client = vi . fn ( )
56
- Client . prototype . connect = vi . fn ( )
56
+ const Client = vi . fn ( function ( ) {
57
+ this . id = count ++
58
+ } )
59
+ Client . prototype . connect = vi . fn ( function ( transport ) { this . transport = transport } )
57
60
Client . prototype . close = vi . fn ( )
58
61
Client . prototype . listTools = vi . fn ( async ( ) => ( {
59
62
tools : [
60
63
{ name : 'tool1' , description : 'tool1 description' , inputSchema : { type : 'object' , properties : { arg : { type : 'string' } } , required : [ ] } } ,
61
64
{ name : 'tool2' , description : 'tool2 description' , inputSchema : { type : 'object' , properties : { arg : { type : 'number' , description : 'desc' } } , required : [ ] } } ,
62
65
]
63
66
} ) )
64
- Client . prototype . callTool = vi . fn ( async ( params ) => {
65
- if ( JSON . stringify ( params . arguments ) . includes ( 'legacy' ) ) return { toolResult : ' result' }
66
- else return { content : [ { type : 'text' , text : ' result' } ] }
67
+ Client . prototype . callTool = vi . fn ( function ( params ) {
68
+ if ( this . id == 1 ) return { toolResult : ` ${ this . id } - ${ params . name } - ${ params . arguments . arg } - result` }
69
+ else return { content : [ { type : 'text' , text : ` ${ this . id } - ${ params . name } - ${ params . arguments . arg } - result` } ] }
67
70
} )
68
71
return { Client }
69
72
} )
70
73
71
74
beforeEach ( ( ) => {
75
+ count = 1
72
76
config = JSON . parse ( JSON . stringify ( mcpConfig ) )
73
77
vi . clearAllMocks ( )
74
78
} )
75
79
76
- test ( 'init ' , async ( ) => {
80
+ test ( 'Initialization ' , async ( ) => {
77
81
const mcp = new Mcp ( app )
78
82
expect ( mcp ) . toBeDefined ( )
79
83
expect ( mcp . clients ) . toBeDefined ( )
80
84
expect ( Client . prototype . connect ) . toHaveBeenCalledTimes ( 0 )
81
85
expect ( await mcp . getStatus ( ) ) . toEqual ( { servers : [ ] , logs : { } } )
82
86
expect ( mcp . getServers ( ) ) . toStrictEqual ( [
83
- { uuid : '1 ' , registryId : '1 ' , state : 'enabled' , type : 'stdio' , command : 'node' , url : 'script.js' , env : { KEY : 'value' } } ,
84
- { uuid : '2 ' , registryId : '2 ' , state : 'enabled' , type : 'sse' , url : 'http://localhost:3000' } ,
85
- { uuid : '3 ' , registryId : '3 ' , state : 'disabled' , type : 'stdio' , command : 'python3' , url : 'script.py' } ,
87
+ { uuid : '1234-5678-90ab ' , registryId : '1234-5678-90ab ' , state : 'enabled' , type : 'stdio' , command : 'node' , url : 'script.js' , env : { KEY : 'value' } } ,
88
+ { uuid : '2345-6789-0abc ' , registryId : '2345-6789-0abc ' , state : 'enabled' , type : 'sse' , url : 'http://localhost:3000' } ,
89
+ { uuid : '3456-7890-abcd ' , registryId : '3456-7890-abcd ' , state : 'disabled' , type : 'stdio' , command : 'python3' , url : 'script.py' } ,
86
90
{ uuid : 'mcp1' , registryId : '@mcp1' , state : 'enabled' , type : 'stdio' , command : 'npx' , url : '-y run mcp1.js' , env : { KEY : 'value' } } ,
87
91
{ uuid : 'mcp2' , registryId : 'mcp2' , state : 'disabled' , type : 'stdio' , command : 'npx' , url : '-y run mcp2.js' , env : undefined }
88
92
] )
89
93
} )
90
94
91
- test ( 'create server' , async ( ) => {
95
+ test ( 'Create server' , async ( ) => {
92
96
const mcp = new Mcp ( app )
93
97
expect ( await mcp . editServer ( { uuid : null , registryId : null , state : 'enabled' , type : 'sse' , url : 'http://localhost:3001' } ) ) . toBe ( true )
94
98
expect ( mcp . getServers ( ) ) . toHaveLength ( 6 )
@@ -110,26 +114,26 @@ test('create server', async () => {
110
114
} )
111
115
} )
112
116
113
- test ( 'edit normal server' , async ( ) => {
117
+ test ( 'Edit normal server' , async ( ) => {
114
118
const mcp = new Mcp ( app )
115
- expect ( await mcp . editServer ( { uuid : '2 ' , registryId : '2 ' , state : 'disabled' , type : 'sse' , url : 'http://localhost:3001' } ) ) . toBe ( true )
119
+ expect ( await mcp . editServer ( { uuid : '2345-6789-0abc ' , registryId : '2345-6789-0abc ' , state : 'disabled' , type : 'sse' , url : 'http://localhost:3001' } ) ) . toBe ( true )
116
120
expect ( mcp . getServers ( ) [ 1 ] ) . toMatchObject ( {
117
- uuid : '2 ' ,
118
- registryId : '2 ' ,
121
+ uuid : '2345-6789-0abc ' ,
122
+ registryId : '2345-6789-0abc ' ,
119
123
state : 'disabled' ,
120
124
type : 'sse' ,
121
125
url : 'http://localhost:3001' ,
122
126
} )
123
127
expect ( config . plugins . mcp . servers [ 1 ] ) . toMatchObject ( {
124
- uuid : '2 ' ,
125
- registryId : '2 ' ,
128
+ uuid : '2345-6789-0abc ' ,
129
+ registryId : '2345-6789-0abc ' ,
126
130
state : 'disabled' ,
127
131
type : 'sse' ,
128
132
url : 'http://localhost:3001' ,
129
133
} )
130
134
} )
131
135
132
- test ( 'edit mcp server' , async ( ) => {
136
+ test ( 'Edit mcp server' , async ( ) => {
133
137
const mcp = new Mcp ( app )
134
138
expect ( await mcp . editServer ( { uuid : 'mcp1' , registryId : '@mcp1' , state : 'enabled' , type : 'stdio' , command : 'node' , url : '-f exec mcp1.js' } ) ) . toBe ( true )
135
139
@@ -167,52 +171,56 @@ test('edit mcp server', async () => {
167
171
expect ( config . plugins . mcp . disabledMcpServers ) . toEqual ( [ 'mcp2' , '@mcp1' ] )
168
172
} )
169
173
170
- test ( 'delete server' , async ( ) => {
174
+ test ( 'Delete server' , async ( ) => {
171
175
const mcp = new Mcp ( app )
172
- expect ( mcp . deleteServer ( '1' ) ) . toBe ( true )
173
- expect ( mcp . getServers ( ) . find ( s => s . uuid === '1' ) ) . toBeUndefined ( )
174
- expect ( config . plugins . mcp . servers . find ( s => s . uuid === '1' ) ) . toBeUndefined ( )
176
+ expect ( mcp . getServers ( ) . length ) . toBe ( 5 )
177
+ expect ( mcp . deleteServer ( '1234-5678-90ab' ) ) . toBe ( true )
178
+ expect ( mcp . getServers ( ) . length ) . toBe ( 4 )
179
+ expect ( mcp . getServers ( ) . find ( s => s . uuid === '1234-5678-90ab' ) ) . toBeUndefined ( )
180
+ expect ( config . plugins . mcp . servers . find ( s => s . uuid === '1234-5678-90ab' ) ) . toBeUndefined ( )
175
181
expect ( mcp . deleteServer ( '@mcp1' ) ) . toBe ( true )
182
+ expect ( mcp . getServers ( ) . length ) . toBe ( 3 )
176
183
expect ( mcp . getServers ( ) . find ( s => s . uuid === 'mcp1' ) ) . toBeUndefined ( )
177
184
expect ( config . mcpServers [ '@mcp1' ] ) . toBeUndefined ( )
178
185
expect ( mcp . deleteServer ( '4' ) ) . toBe ( false )
186
+ expect ( mcp . getServers ( ) . length ) . toBe ( 3 )
179
187
expect ( mcp . deleteServer ( '@mcp2' ) ) . toBe ( false )
180
188
} )
181
189
182
- test ( 'connect ' , async ( ) => {
190
+ test ( 'Connect ' , async ( ) => {
183
191
const mcp = new Mcp ( app )
184
192
expect ( await mcp . connect ( ) )
185
193
expect ( mcp . clients ) . toHaveLength ( 3 )
186
194
expect ( await mcp . getStatus ( ) ) . toStrictEqual ( {
187
195
servers : [
188
- { uuid : '1 ' , registryId : '1 ' , state : 'enabled' , type : 'stdio' , command : 'node' , url : 'script.js' , env : { KEY : 'value' } , tools : [ 'tool1___1 ' , 'tool2___1 ' ] } ,
189
- { uuid : '2 ' , registryId : '2 ' , state : 'enabled' , type : 'sse' , url : 'http://localhost:3000' , tools : [ 'tool1___2 ' , 'tool2___2 ' ] } ,
196
+ { uuid : '1234-5678-90ab ' , registryId : '1234-5678-90ab ' , state : 'enabled' , type : 'stdio' , command : 'node' , url : 'script.js' , env : { KEY : 'value' } , tools : [ 'tool1___90ab ' , 'tool2___90ab ' ] } ,
197
+ { uuid : '2345-6789-0abc ' , registryId : '2345-6789-0abc ' , state : 'enabled' , type : 'sse' , url : 'http://localhost:3000' , tools : [ 'tool1___0abc ' , 'tool2___0abc ' ] } ,
190
198
{ uuid : 'mcp1' , registryId : '@mcp1' , state : 'enabled' , type : 'stdio' , command : 'npx' , url : '-y run mcp1.js' , env : { KEY : 'value' } , tools : [ 'tool1___mcp1' , 'tool2___mcp1' ] } ,
191
199
] ,
192
200
logs : {
193
- '1 ' : [ ] ,
194
- '2 ' : [ ] ,
195
- '3 ' : [ ] ,
201
+ '1234-5678-90ab ' : [ ] ,
202
+ '2345-6789-0abc ' : [ ] ,
203
+ '3456-7890-abcd ' : [ ] ,
196
204
'mcp1' : [ ] ,
197
205
'mcp2' : [ ] ,
198
206
}
199
207
} )
200
208
expect ( await mcp . getTools ( ) ) . toStrictEqual ( [
201
209
{
202
210
type : 'function' ,
203
- function : { name : 'tool1___1 ' , description : 'tool1 description' , parameters : { type : 'object' , properties : { arg : { type : 'string' , description : 'arg' } } , required : [ ] } }
211
+ function : { name : 'tool1___90ab ' , description : 'tool1 description' , parameters : { type : 'object' , properties : { arg : { type : 'string' , description : 'arg' } } , required : [ ] } }
204
212
} ,
205
213
{
206
214
type : 'function' ,
207
- function : { name : 'tool2___1 ' , description : 'tool2 description' , parameters : { type : 'object' , properties : { arg : { type : 'number' , description : 'desc' } } , required : [ ] } }
215
+ function : { name : 'tool2___90ab ' , description : 'tool2 description' , parameters : { type : 'object' , properties : { arg : { type : 'number' , description : 'desc' } } , required : [ ] } }
208
216
} ,
209
217
{
210
218
type : 'function' ,
211
- function : { name : 'tool1___2 ' , description : 'tool1 description' , parameters : { type : 'object' , properties : { arg : { type : 'string' , description : 'arg' } } , required : [ ] } }
219
+ function : { name : 'tool1___0abc ' , description : 'tool1 description' , parameters : { type : 'object' , properties : { arg : { type : 'string' , description : 'arg' } } , required : [ ] } }
212
220
} ,
213
221
{
214
222
type : 'function' ,
215
- function : { name : 'tool2___2 ' , description : 'tool2 description' , parameters : { type : 'object' , properties : { arg : { type : 'number' , description : 'desc' } } , required : [ ] } }
223
+ function : { name : 'tool2___0abc ' , description : 'tool2 description' , parameters : { type : 'object' , properties : { arg : { type : 'number' , description : 'desc' } } , required : [ ] } }
216
224
} ,
217
225
{
218
226
type : 'function' ,
@@ -225,24 +233,26 @@ test('connect', async () => {
225
233
] )
226
234
} )
227
235
228
- test ( 'call tool' , async ( ) => {
236
+ test ( 'Call tool' , async ( ) => {
229
237
const mcp = new Mcp ( app )
230
238
await mcp . connect ( )
231
- expect ( await mcp . callTool ( 'tool1___1' , { arg : 'legacy' } ) ) . toStrictEqual ( { toolResult : 'result' } )
232
- expect ( await mcp . callTool ( 'tool2___1' , { arg : 'modern' } ) ) . toStrictEqual ( { content : [ { type : 'text' , text : 'result' } ] } )
239
+ expect ( await mcp . callTool ( 'tool1___90ab' , { arg : 'arg1' } ) ) . toStrictEqual ( { toolResult : '1-tool1-arg1-result' } )
240
+ expect ( await mcp . callTool ( 'tool2___90ab' , { arg : 'arg2' } ) ) . toStrictEqual ( { toolResult : '1-tool2-arg2-result' } )
241
+ expect ( await mcp . callTool ( 'tool1___0abc' , { arg : 'arg3' } ) ) . toStrictEqual ( { content : [ { type : 'text' , text : '2-tool1-arg3-result' } ] } )
242
+ expect ( await mcp . callTool ( 'tool2___0abc' , { arg : 'arg4' } ) ) . toStrictEqual ( { content : [ { type : 'text' , text : '2-tool2-arg4-result' } ] } )
233
243
await expect ( ( ) => mcp . callTool ( 'tool3___1' , { arg : 'modern' } ) ) . rejects . toThrowError ( / n o t f o u n d / )
234
244
} )
235
245
236
- test ( 'disconnect ' , async ( ) => {
246
+ test ( 'Disconnect ' , async ( ) => {
237
247
const mcp = new Mcp ( app )
238
248
expect ( await mcp . connect ( ) )
239
249
expect ( mcp . clients ) . toHaveLength ( 3 )
240
- expect ( mcp . deleteServer ( '1 ' ) ) . toBe ( true )
250
+ expect ( mcp . deleteServer ( '1234-5678-90ab ' ) ) . toBe ( true )
241
251
expect ( Client . prototype . close ) . toHaveBeenCalledTimes ( 1 )
242
252
expect ( mcp . clients ) . toHaveLength ( 2 )
243
253
} )
244
254
245
- test ( 'reload ' , async ( ) => {
255
+ test ( 'Reload ' , async ( ) => {
246
256
const mcp = new Mcp ( app )
247
257
expect ( await mcp . connect ( ) )
248
258
expect ( mcp . clients ) . toHaveLength ( 3 )
@@ -252,7 +262,7 @@ test('reload', async () => {
252
262
expect ( Client . prototype . close ) . toHaveBeenCalledTimes ( 3 )
253
263
} )
254
264
255
- test ( 'install smithery' , async ( ) => {
265
+ test ( 'Install smithery' , async ( ) => {
256
266
const mcp = new Mcp ( app )
257
267
expect ( await mcp . getInstallCommand ( 'smithery' , 'server' ) ) . toBe ( 'npx -y @smithery/cli@latest install server --client witsy' )
258
268
expect ( await mcp . installServer ( 'smithery' , 'server' ) ) . toBe ( true )
0 commit comments