55 . "github.com/onsi/gomega"
66
77 "context"
8+ "encoding/json"
89 "fmt"
910 "net/http"
1011 "net/http/httptest"
@@ -41,10 +42,13 @@ var _ = Describe("Basic Integration", Ordered, func() {
4142 go func () {
4243 defer GinkgoRecover ()
4344 mcpServer := & mcpfile.MCPServer {
44- Name : mcpConfig .Name ,
45- Version : mcpConfig .Version ,
46- Runtime : mcpConfig .Runtime ,
47- Tools : mcpConfig .Tools ,
45+ Name : mcpConfig .Name ,
46+ Version : mcpConfig .Version ,
47+ Runtime : mcpConfig .Runtime ,
48+ Instructions : mcpConfig .Instructions ,
49+ Tools : mcpConfig .Tools ,
50+ Prompts : mcpConfig .Prompts ,
51+ Resources : mcpConfig .Resources ,
4852 }
4953 err := mcpserver .RunServer (ctx , mcpServer )
5054 if err != nil && ! strings .Contains (err .Error (), "Server closed" ) {
@@ -103,9 +107,11 @@ var _ = Describe("Basic Integration", Ordered, func() {
103107 transport := & mcp.StreamableClientTransport {
104108 Endpoint : mcpServerURL ,
105109 }
106- var err error
107- session , err = client .Connect (context .Background (), transport , nil )
108- Expect (err ).NotTo (HaveOccurred ())
110+ Eventually (func () error {
111+ var err error
112+ session , err = client .Connect (context .Background (), transport , nil )
113+ return err
114+ }, 2 * time .Second , 100 * time .Millisecond ).Should (Succeed ())
109115 })
110116
111117 AfterEach (func () {
@@ -121,6 +127,13 @@ var _ = Describe("Basic Integration", Ordered, func() {
121127 Expect (initResult .ServerInfo ).NotTo (BeNil ())
122128 })
123129
130+ It ("should return server instructions" , func () {
131+ By ("verifying instructions are present" )
132+ initResult := session .InitializeResult ()
133+ Expect (initResult ).NotTo (BeNil ())
134+ Expect (initResult .Instructions ).To (Equal ("This is a test HTTP server with tools, prompts, and resources for integration testing." ))
135+ })
136+
124137 It ("should list available tools" , func () {
125138 By ("listing tools" )
126139 toolsResult , err := session .ListTools (context .Background (), & mcp.ListToolsParams {})
@@ -148,6 +161,53 @@ var _ = Describe("Basic Integration", Ordered, func() {
148161 Expect (ok ).To (BeTrue ())
149162 Expect (textResult .Text ).To (MatchJSON (`{"users": [{"name": "John Doe", "email": "john@test_company.com"}]}` ))
150163 })
164+
165+ It ("should list available prompts" , func () {
166+ By ("listing prompts" )
167+ promptsResult , err := session .ListPrompts (context .Background (), & mcp.ListPromptsParams {})
168+ Expect (err ).NotTo (HaveOccurred ())
169+ Expect (promptsResult .Prompts ).To (HaveLen (1 ))
170+ Expect (promptsResult .Prompts [0 ].Name ).To (Equal ("greeting_prompt" ))
171+ })
172+
173+ It ("should successfully call prompts" , func () {
174+ By ("calling prompt" )
175+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
176+ defer cancel ()
177+
178+ result , err := session .GetPrompt (ctx , & mcp.GetPromptParams {
179+ Name : "greeting_prompt" ,
180+ Arguments : map [string ]string {
181+ "userName" : "Alice" ,
182+ },
183+ })
184+ Expect (err ).NotTo (HaveOccurred ())
185+ Expect (result ).NotTo (BeNil ())
186+ Expect (result .Messages ).To (HaveLen (1 ))
187+ Expect (result .Messages [0 ].Content .(* mcp.TextContent ).Text ).To (ContainSubstring ("Hello, Alice" ))
188+ })
189+
190+ It ("should list available resources" , func () {
191+ By ("listing resources" )
192+ resourcesResult , err := session .ListResources (context .Background (), & mcp.ListResourcesParams {})
193+ Expect (err ).NotTo (HaveOccurred ())
194+ Expect (resourcesResult .Resources ).To (HaveLen (1 ))
195+ Expect (resourcesResult .Resources [0 ].Name ).To (Equal ("server_info" ))
196+ })
197+
198+ It ("should successfully read resources" , func () {
199+ By ("reading resource" )
200+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
201+ defer cancel ()
202+
203+ result , err := session .ReadResource (ctx , & mcp.ReadResourceParams {
204+ URI : fmt .Sprintf ("%s/server/info" , backendServer .URL ),
205+ })
206+ Expect (err ).NotTo (HaveOccurred ())
207+ Expect (result ).NotTo (BeNil ())
208+ Expect (result .Contents ).To (HaveLen (1 ))
209+ Expect (result .Contents [0 ].Text ).To (MatchJSON (`{"server":"test-server","version":"1.0","status":"running"}` ))
210+ })
151211 })
152212 })
153213
@@ -171,10 +231,12 @@ var _ = Describe("Basic Integration", Ordered, func() {
171231 go func () {
172232 defer GinkgoRecover ()
173233 mcpServer := & mcpfile.MCPServer {
174- Name : mcpConfig .Name ,
175- Version : mcpConfig .Version ,
176- Runtime : mcpConfig .Runtime ,
177- Tools : mcpConfig .Tools ,
234+ Name : mcpConfig .Name ,
235+ Version : mcpConfig .Version ,
236+ Runtime : mcpConfig .Runtime ,
237+ Tools : mcpConfig .Tools ,
238+ Prompts : mcpConfig .Prompts ,
239+ Resources : mcpConfig .Resources ,
178240 }
179241 err := mcpserver .RunServer (ctx , mcpServer )
180242 if err != nil && ! strings .Contains (err .Error (), "Server closed" ) {
@@ -193,7 +255,7 @@ var _ = Describe("Basic Integration", Ordered, func() {
193255 }
194256 })
195257
196- Describe ("CLI Tool Execution" , func () {
258+ Describe ("CLI Commands Execution" , func () {
197259 var (
198260 client * mcp.Client
199261 session * mcp.ClientSession
@@ -210,9 +272,12 @@ var _ = Describe("Basic Integration", Ordered, func() {
210272 transport := & mcp.StreamableClientTransport {
211273 Endpoint : fmt .Sprintf ("http://localhost:%d/mcp" , mcpServerPort ),
212274 }
213- var err error
214- session , err = client .Connect (context .Background (), transport , nil )
215- Expect (err ).NotTo (HaveOccurred ())
275+
276+ Eventually (func () error {
277+ var err error
278+ session , err = client .Connect (context .Background (), transport , nil )
279+ return err
280+ }, 2 * time .Second , 100 * time .Millisecond ).Should (Succeed ())
216281 })
217282
218283 AfterEach (func () {
@@ -240,13 +305,86 @@ var _ = Describe("Basic Integration", Ordered, func() {
240305 Expect (ok ).To (BeTrue ())
241306 Expect (textResult .Text ).NotTo (BeEmpty ())
242307 })
308+
309+ It ("should list available prompts" , func () {
310+ By ("listing prompts" )
311+ promptsResult , err := session .ListPrompts (context .Background (), & mcp.ListPromptsParams {})
312+ Expect (err ).NotTo (HaveOccurred ())
313+ Expect (promptsResult .Prompts ).To (HaveLen (1 ))
314+ Expect (promptsResult .Prompts [0 ].Name ).To (Equal ("greeting_prompt" ))
315+ })
316+
317+ It ("should execute CLI prompt invocation successfully" , func () {
318+ By ("calling CLI prompt" )
319+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
320+ defer cancel ()
321+
322+ result , err := session .GetPrompt (ctx , & mcp.GetPromptParams {
323+ Name : "greeting_prompt" ,
324+ Arguments : map [string ]string {
325+ "userName" : "Bob" ,
326+ },
327+ })
328+ Expect (err ).NotTo (HaveOccurred ())
329+ Expect (result ).NotTo (BeNil ())
330+ Expect (result .Messages ).To (HaveLen (1 ))
331+ Expect (result .Messages [0 ].Content .(* mcp.TextContent ).Text ).To (ContainSubstring ("Hello, Bob" ))
332+ })
333+
334+ It ("should list available resources" , func () {
335+ By ("listing resources" )
336+ resourcesResult , err := session .ListResources (context .Background (), & mcp.ListResourcesParams {})
337+ Expect (err ).NotTo (HaveOccurred ())
338+ Expect (resourcesResult .Resources ).To (HaveLen (1 ))
339+ Expect (resourcesResult .Resources [0 ].Name ).To (Equal ("server_info" ))
340+ })
341+
342+ It ("should read CLI resource invocation successfully" , func () {
343+ By ("reading CLI resource" )
344+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
345+ defer cancel ()
346+
347+ result , err := session .ReadResource (ctx , & mcp.ReadResourceParams {
348+ URI : "file://tmp/server-info.json" ,
349+ })
350+ Expect (err ).NotTo (HaveOccurred ())
351+ Expect (result ).NotTo (BeNil ())
352+ Expect (result .Contents ).To (HaveLen (1 ))
353+ Expect (result .Contents [0 ].URI ).To (Equal ("file://tmp/server-info.json" ))
354+ Expect (result .Contents [0 ].Text ).To (Equal ("test-server-cli-server version 1.0 running\n " ))
355+ })
243356 })
244357 })
245358})
246359
247360func createMockBackendServerIntegration () * httptest.Server {
248361 By ("creating mock backend server" )
249362 return httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
363+ if r .URL .Path == "/server/info" {
364+ w .Header ().Set ("Content-Type" , "application/json" )
365+ _ , err := fmt .Fprintln (w , `{"server":"test-server","version":"1.0","status":"running"}` )
366+ Expect (err ).NotTo (HaveOccurred ())
367+ return
368+ }
369+ if r .URL .Path == "/prompts/greeting_prompt" && r .Method == "POST" {
370+ // Read and parse the request body to extract userName
371+ var requestBody map [string ]interface {}
372+ if err := json .NewDecoder (r .Body ).Decode (& requestBody ); err == nil {
373+ if userName , ok := requestBody ["userName" ].(string ); ok {
374+ w .Header ().Set ("Content-Type" , "application/json" )
375+ response := fmt .Sprintf (`{"message":"Hello, %s! Welcome to our system."}` , userName )
376+ _ , err := fmt .Fprintln (w , response )
377+ Expect (err ).NotTo (HaveOccurred ())
378+ return
379+ }
380+ }
381+ // Fallback response if userName not found
382+ w .Header ().Set ("Content-Type" , "application/json" )
383+ _ , err := fmt .Fprintln (w , `{"message":"Hello! Welcome to our system."}` )
384+ Expect (err ).NotTo (HaveOccurred ())
385+ return
386+ }
387+ // Default response for user endpoints
250388 _ , err := fmt .Fprintln (w , `{"users": [{"name": "John Doe", "email": "john@test_company.com"}]}` )
251389 Expect (err ).NotTo (HaveOccurred ())
252390 }))
@@ -259,6 +397,7 @@ func createBasicTestMCPConfig(backendURL string, port int) *mcpfile.MCPFile {
259397mcpFileVersion: 0.1.0
260398name: test-server
261399version: "1.0"
400+ instructions: "This is a test HTTP server with tools, prompts, and resources for integration testing."
262401runtime:
263402 streamableHttpConfig:
264403 port: %d
@@ -280,7 +419,31 @@ tools:
280419 http:
281420 url: "%s/{companyName}/users"
282421 method: GET
283- ` , port , backendURL )
422+ prompts:
423+ - name: greeting_prompt
424+ description: Generate a greeting message for a user
425+ inputSchema:
426+ type: object
427+ properties:
428+ userName:
429+ type: string
430+ description: Name of the user to greet
431+ required:
432+ - userName
433+ invocation:
434+ http:
435+ method: POST
436+ url: "%s/prompts/greeting_prompt"
437+ resources:
438+ - name: server_info
439+ description: Information about the server
440+ uri: "%s/server/info"
441+ mimeType: "application/json"
442+ invocation:
443+ http:
444+ url: "%s/server/info"
445+ method: GET
446+ ` , port , backendURL , backendURL , backendURL , backendURL )
284447
285448 tmpfile , err := os .CreateTemp ("" , "mcp-basic-*.yaml" )
286449 Expect (err ).NotTo (HaveOccurred ())
@@ -331,6 +494,28 @@ tools:
331494 invocation:
332495 cli:
333496 command: "ls -la {path}"
497+ prompts:
498+ - name: greeting_prompt
499+ description: Generate a greeting message for a user
500+ inputSchema:
501+ type: object
502+ properties:
503+ userName:
504+ type: string
505+ description: Name of the user to greet
506+ required:
507+ - userName
508+ invocation:
509+ cli:
510+ command: "echo 'Hello, {userName}! Welcome to our system.'"
511+ resources:
512+ - name: server_info
513+ description: Information about the server
514+ uri: "file://tmp/server-info.json"
515+ mimeType: "text/plain"
516+ invocation:
517+ cli:
518+ command: "echo 'test-server-cli-server version 1.0 running'"
334519` , port )
335520
336521 tmpfile , err := os .CreateTemp ("" , "mcp-cli-*.yaml" )
0 commit comments