MCPcopy Index your code
hub / github.com/coder/coder / TestMCPServerToolInvocation

Function TestMCPServerToolInvocation

coderd/x/chatd/chatd_test.go:7663–7845  ·  view source on GitHub ↗

TestMCPServerToolInvocation verifies that when a chat has mcp_server_ids set, the chat loop connects to those MCP servers, discovers their tools, and the LLM can invoke them. NOTE: This test uses a raw database.Store (no dbauthz wrapper). The chatd RBAC authorization of GetMCPServerConfigsByIDs (wh

(t *testing.T)

Source from the content-addressed store, hash-verified

7661// requires ActionRead on ResourceDeploymentConfig) is covered by
7662// the chatd role definition tests, not here.
7663func TestMCPServerToolInvocation(t *testing.T) {
7664 t.Parallel()
7665
7666 db, ps := dbtestutil.NewDB(t)
7667 ctx := testutil.Context(t, testutil.WaitLong)
7668
7669 // Start a real MCP server that exposes an "echo" tool.
7670 mcpSrv := mcpserver.NewMCPServer("test-mcp", "1.0.0")
7671 mcpSrv.AddTools(mcpserver.ServerTool{
7672 Tool: mcpgo.NewTool("echo",
7673 mcpgo.WithDescription("Echoes the input"),
7674 mcpgo.WithString("input",
7675 mcpgo.Description("The input string"),
7676 mcpgo.Required(),
7677 ),
7678 ),
7679 Handler: func(_ context.Context, req mcpgo.CallToolRequest) (*mcpgo.CallToolResult, error) {
7680 input, _ := req.GetArguments()["input"].(string)
7681 return mcpgo.NewToolResultText("echo: " + input), nil
7682 },
7683 })
7684 mcpHTTP := mcpserver.NewStreamableHTTPServer(mcpSrv)
7685 mcpTS := httptest.NewServer(mcpHTTP)
7686 t.Cleanup(mcpTS.Close)
7687
7688 // Track which tool names are sent to the LLM and capture
7689 // whether the MCP tool result appears in the second call.
7690 var (
7691 callCount atomic.Int32
7692 llmToolNames []string
7693 llmToolsMu sync.Mutex
7694 foundMCPResult atomic.Bool
7695 )
7696
7697 openAIURL := chattest.NewOpenAI(t, func(req *chattest.OpenAIRequest) chattest.OpenAIResponse {
7698 if !req.Stream {
7699 return chattest.OpenAINonStreamingResponse("title")
7700 }
7701
7702 // Record tool names from the first streamed call.
7703 if callCount.Add(1) == 1 {
7704 names := make([]string, 0, len(req.Tools))
7705 for _, tool := range req.Tools {
7706 names = append(names, tool.Function.Name)
7707 }
7708 llmToolsMu.Lock()
7709 llmToolNames = names
7710 llmToolsMu.Unlock()
7711
7712 // Ask the LLM to call the MCP echo tool.
7713 return chattest.OpenAIStreamingResponse(
7714 chattest.OpenAIToolCallChunk(
7715 "test-mcp__echo",
7716 `{"input":"hello from LLM"}`,
7717 ),
7718 )
7719 }
7720

Callers

nothing calls this directly

Calls 15

EXPECTMethod · 0.95
NewDBFunction · 0.92
ContextFunction · 0.92
NewOpenAIFunction · 0.92
OpenAIStreamingResponseFunction · 0.92
OpenAIToolCallChunkFunction · 0.92
OpenAITextChunksFunction · 0.92
MCPServerConfigFunction · 0.92
NewMockAgentConnFunction · 0.92
ChatMessageTextFunction · 0.92
EventuallyFunction · 0.92

Tested by

no test coverage detected