From f80bce2d3957cae4f171e48c9d061628e2362e22 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 09:26:11 +0530 Subject: [PATCH 01/24] Add serve-agents Command Stub --- go/cli/internal/cli/mcp/root.go | 1 + go/cli/internal/cli/mcp/serve_agents.go | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 go/cli/internal/cli/mcp/serve_agents.go diff --git a/go/cli/internal/cli/mcp/root.go b/go/cli/internal/cli/mcp/root.go index 43d8932a8..93639baf3 100644 --- a/go/cli/internal/cli/mcp/root.go +++ b/go/cli/internal/cli/mcp/root.go @@ -18,6 +18,7 @@ Model Context Protocol servers with dynamic tool loading.`, mcpCmd.AddCommand(DeployCmd) mcpCmd.AddCommand(AddToolCmd) mcpCmd.AddCommand(RunCmd) + mcpCmd.AddCommand(ServeAgentsCmd) mcpCmd.AddCommand(SecretsCmd) return mcpCmd diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go new file mode 100644 index 000000000..0b35f45ab --- /dev/null +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -0,0 +1,8 @@ +package mcp + +import "github.com/spf13/cobra" + +var ServeAgentsCmd = &cobra.Command{ + Use: "serve-agents", + Short: "Serve kagent agents via MCP", +} From 9daf77d3a6840fca335f170a4e493dd5d2759fd9 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 09:34:14 +0530 Subject: [PATCH 02/24] Start an Empty mcp-go Server (stdio) --- go/cli/internal/cli/mcp/serve_agents.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 0b35f45ab..01f47f27f 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -1,8 +1,20 @@ package mcp -import "github.com/spf13/cobra" +import ( + "github.com/kagent-dev/kagent/go/internal/version" + mcpserver "github.com/mark3labs/mcp-go/server" + "github.com/spf13/cobra" +) var ServeAgentsCmd = &cobra.Command{ Use: "serve-agents", Short: "Serve kagent agents via MCP", + RunE: func(cmd *cobra.Command, args []string) error { + s := mcpserver.NewMCPServer( + "kagent-agents", + version.Version, + mcpserver.WithToolCapabilities(false), + ) + return mcpserver.ServeStdio(s) + }, } From cc34412b73f1b6a7d925147aee6ef41ad0aa163f Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 09:53:50 +0530 Subject: [PATCH 03/24] echo tool --- go/cli/internal/cli/mcp/serve_agents.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 01f47f27f..7b6fe0848 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -1,7 +1,10 @@ package mcp import ( + "context" + "github.com/kagent-dev/kagent/go/internal/version" + "github.com/mark3labs/mcp-go/mcp" mcpserver "github.com/mark3labs/mcp-go/server" "github.com/spf13/cobra" ) @@ -15,6 +18,16 @@ var ServeAgentsCmd = &cobra.Command{ version.Version, mcpserver.WithToolCapabilities(false), ) + s.AddTool(mcp.NewTool("echo", + mcp.WithDescription("Echo back the input message"), + mcp.WithString("message", mcp.Description("Message to echo"), mcp.Required()), + ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + message, err := request.RequireString("message") + if err != nil { + return mcp.NewToolResultError(err.Error()), nil + } + return mcp.NewToolResultText(message), nil + }) return mcpserver.ServeStdio(s) }, } From 69aba671926dec034f91ca5a50aba1df091db7d2 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 09:57:51 +0530 Subject: [PATCH 04/24] Milestone 5: Clean Shutdown via Cobra Context --- go/cli/internal/cli/mcp/serve_agents.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 7b6fe0848..26c32c7b1 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -2,6 +2,7 @@ package mcp import ( "context" + "os" "github.com/kagent-dev/kagent/go/internal/version" "github.com/mark3labs/mcp-go/mcp" @@ -28,6 +29,7 @@ var ServeAgentsCmd = &cobra.Command{ } return mcp.NewToolResultText(message), nil }) - return mcpserver.ServeStdio(s) + stdioServer := mcpserver.NewStdioServer(s) + return stdioServer.Listen(cmd.Context(), os.Stdin, os.Stdout) }, } From 83f4f84ac32e3656d455de7644e8d635ba16313d Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 10:03:53 +0530 Subject: [PATCH 05/24] Milestone 6 best-effort, non-blocking /api/agents listing cal --- go/cli/internal/cli/mcp/serve_agents.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 26c32c7b1..800bf572c 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -4,6 +4,7 @@ import ( "context" "os" + "github.com/kagent-dev/kagent/go/cli/internal/config" "github.com/kagent-dev/kagent/go/internal/version" "github.com/mark3labs/mcp-go/mcp" mcpserver "github.com/mark3labs/mcp-go/server" @@ -19,6 +20,9 @@ var ServeAgentsCmd = &cobra.Command{ version.Version, mcpserver.WithToolCapabilities(false), ) + if cfg, err := config.Get(); err == nil { + go func() { _, _ = cfg.Client().Agent.ListAgents(cmd.Context()) }() + } s.AddTool(mcp.NewTool("echo", mcp.WithDescription("Echo back the input message"), mcp.WithString("message", mcp.Description("Message to echo"), mcp.Required()), From c6730e3670d58af1d88d37039a9723ae1b4b9ec8 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 10:12:45 +0530 Subject: [PATCH 06/24] Milestone 7: Register first agent tool (stub) --- go/cli/internal/cli/mcp/serve_agents.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 800bf572c..960221c9f 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -21,7 +21,24 @@ var ServeAgentsCmd = &cobra.Command{ mcpserver.WithToolCapabilities(false), ) if cfg, err := config.Get(); err == nil { - go func() { _, _ = cfg.Client().Agent.ListAgents(cmd.Context()) }() + if resp, err := cfg.Client().Agent.ListAgents(cmd.Context()); err == nil { + for _, agent := range resp.Data { + if !agent.Accepted || !agent.DeploymentReady || agent.Agent == nil { + continue + } + toolName, agentNS, agentName := agent.ID, agent.Agent.Namespace, agent.Agent.Name + s.AddTool(mcp.NewTool(toolName, + mcp.WithDescription("kagent agent "+agentNS+"/"+agentName), + mcp.WithString("task", mcp.Description("Task to run"), mcp.Required()), + ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if _, err := request.RequireString("task"); err != nil { + return mcp.NewToolResultError(err.Error()), nil + } + return mcp.NewToolResultError("agent tool not wired yet: " + agentNS + "/" + agentName), nil + }) + break + } + } } s.AddTool(mcp.NewTool("echo", mcp.WithDescription("Echo back the input message"), From 88bc88c90ef2a6de89388008a7a60afb56128d65 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 10:13:03 +0530 Subject: [PATCH 07/24] Milestone 8: Register all agent tools (stub) --- go/cli/internal/cli/mcp/serve_agents.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 960221c9f..4bcb7cc46 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -36,7 +36,6 @@ var ServeAgentsCmd = &cobra.Command{ } return mcp.NewToolResultError("agent tool not wired yet: " + agentNS + "/" + agentName), nil }) - break } } } From 5c3355195d11ac425092e2030cd2c46f033c47c0 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 10:13:42 +0530 Subject: [PATCH 08/24] Milestone 9: Bridge agent tools to A2A --- go/cli/internal/cli/mcp/serve_agents.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 4bcb7cc46..e226d7a9a 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -2,6 +2,7 @@ package mcp import ( "context" + "fmt" "os" "github.com/kagent-dev/kagent/go/cli/internal/config" @@ -9,6 +10,8 @@ import ( "github.com/mark3labs/mcp-go/mcp" mcpserver "github.com/mark3labs/mcp-go/server" "github.com/spf13/cobra" + a2aclient "trpc.group/trpc-go/trpc-a2a-go/client" + "trpc.group/trpc-go/trpc-a2a-go/protocol" ) var ServeAgentsCmd = &cobra.Command{ @@ -31,10 +34,26 @@ var ServeAgentsCmd = &cobra.Command{ mcp.WithDescription("kagent agent "+agentNS+"/"+agentName), mcp.WithString("task", mcp.Description("Task to run"), mcp.Required()), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - if _, err := request.RequireString("task"); err != nil { + task, err := request.RequireString("task") + if err != nil { return mcp.NewToolResultError(err.Error()), nil } - return mcp.NewToolResultError("agent tool not wired yet: " + agentNS + "/" + agentName), nil + a2aURL := fmt.Sprintf("%s/api/a2a/%s/%s", cfg.KAgentURL, agentNS, agentName) + client, err := a2aclient.NewA2AClient(a2aURL, a2aclient.WithTimeout(cfg.Timeout)) + if err != nil { + return mcp.NewToolResultErrorFromErr("a2a client", err), nil + } + result, err := client.SendMessage(ctx, protocol.SendMessageParams{Message: protocol.Message{ + Kind: protocol.KindMessage, Role: protocol.MessageRoleUser, Parts: []protocol.Part{protocol.NewTextPart(task)}, + }}) + if err != nil { + return mcp.NewToolResultErrorFromErr("a2a send", err), nil + } + raw, err := result.MarshalJSON() + if err != nil { + return mcp.NewToolResultErrorFromErr("marshal result", err), nil + } + return mcp.NewToolResultText(string(raw)), nil }) } } From 5ea346fe55519c01da3252e93476052435ee09a7 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 10:14:15 +0530 Subject: [PATCH 09/24] Milestone 10: Support context_id and history_length --- go/cli/internal/cli/mcp/serve_agents.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index e226d7a9a..799a81aff 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -32,20 +32,36 @@ var ServeAgentsCmd = &cobra.Command{ toolName, agentNS, agentName := agent.ID, agent.Agent.Namespace, agent.Agent.Name s.AddTool(mcp.NewTool(toolName, mcp.WithDescription("kagent agent "+agentNS+"/"+agentName), + mcp.WithString("context_id", mcp.Description("A2A context ID")), + mcp.WithNumber("history_length", mcp.Description("Requested history length")), mcp.WithString("task", mcp.Description("Task to run"), mcp.Required()), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { task, err := request.RequireString("task") if err != nil { return mcp.NewToolResultError(err.Error()), nil } + contextID := request.GetString("context_id", "") + historyLength := request.GetInt("history_length", 0) + var contextIDPtr *string + if contextID != "" { + contextIDPtr = &contextID + } + var historyLengthPtr *int + if historyLength > 0 { + historyLengthPtr = &historyLength + } a2aURL := fmt.Sprintf("%s/api/a2a/%s/%s", cfg.KAgentURL, agentNS, agentName) client, err := a2aclient.NewA2AClient(a2aURL, a2aclient.WithTimeout(cfg.Timeout)) if err != nil { return mcp.NewToolResultErrorFromErr("a2a client", err), nil } - result, err := client.SendMessage(ctx, protocol.SendMessageParams{Message: protocol.Message{ - Kind: protocol.KindMessage, Role: protocol.MessageRoleUser, Parts: []protocol.Part{protocol.NewTextPart(task)}, - }}) + params := protocol.SendMessageParams{ + Configuration: &protocol.SendMessageConfiguration{HistoryLength: historyLengthPtr}, + Message: protocol.Message{ + Kind: protocol.KindMessage, Role: protocol.MessageRoleUser, ContextID: contextIDPtr, Parts: []protocol.Part{protocol.NewTextPart(task)}, + }, + } + result, err := client.SendMessage(ctx, params) if err != nil { return mcp.NewToolResultErrorFromErr("a2a send", err), nil } From 048f3d3aaf813b86ac437af7bf5709c707959adc Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 10:14:55 +0530 Subject: [PATCH 10/24] Milestone 11: Return extracted A2A text --- go/cli/internal/cli/mcp/serve_agents.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 799a81aff..8bc67df12 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -6,6 +6,7 @@ import ( "os" "github.com/kagent-dev/kagent/go/cli/internal/config" + "github.com/kagent-dev/kagent/go/internal/a2a" "github.com/kagent-dev/kagent/go/internal/version" "github.com/mark3labs/mcp-go/mcp" mcpserver "github.com/mark3labs/mcp-go/server" @@ -65,11 +66,26 @@ var ServeAgentsCmd = &cobra.Command{ if err != nil { return mcp.NewToolResultErrorFromErr("a2a send", err), nil } - raw, err := result.MarshalJSON() - if err != nil { - return mcp.NewToolResultErrorFromErr("marshal result", err), nil + var text string + switch a2aResult := result.Result.(type) { + case *protocol.Message: + text = a2a.ExtractText(*a2aResult) + case *protocol.Task: + if a2aResult.Status.Message != nil { + text = a2a.ExtractText(*a2aResult.Status.Message) + } + for _, artifact := range a2aResult.Artifacts { + text += a2a.ExtractText(protocol.Message{Parts: artifact.Parts}) + } + } + if text == "" { + raw, err := result.MarshalJSON() + if err != nil { + return mcp.NewToolResultErrorFromErr("marshal result", err), nil + } + text = string(raw) } - return mcp.NewToolResultText(string(raw)), nil + return mcp.NewToolResultText(text), nil }) } } From 700e24428542555fcae1199607e30e4f4d788a81 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 12 Jan 2026 10:15:16 +0530 Subject: [PATCH 11/24] Milestone 12: Remove temporary echo tool --- go/cli/internal/cli/mcp/serve_agents.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 8bc67df12..baca50681 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -90,16 +90,6 @@ var ServeAgentsCmd = &cobra.Command{ } } } - s.AddTool(mcp.NewTool("echo", - mcp.WithDescription("Echo back the input message"), - mcp.WithString("message", mcp.Description("Message to echo"), mcp.Required()), - ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - message, err := request.RequireString("message") - if err != nil { - return mcp.NewToolResultError(err.Error()), nil - } - return mcp.NewToolResultText(message), nil - }) stdioServer := mcpserver.NewStdioServer(s) return stdioServer.Listen(cmd.Context(), os.Stdin, os.Stdout) }, From 190ae09804cb179a566c70efe4c4109d9e92c168 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Tue, 13 Jan 2026 13:53:12 +0530 Subject: [PATCH 12/24] MCP serve-agents: list/invoke tools + http transport --- go/cli/internal/cli/mcp/serve_agents.go | 211 ++++++++++++++++-------- 1 file changed, 146 insertions(+), 65 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index baca50681..148ca466c 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -3,7 +3,11 @@ package mcp import ( "context" "fmt" + "net/http" "os" + "strings" + "sync" + "time" "github.com/kagent-dev/kagent/go/cli/internal/config" "github.com/kagent-dev/kagent/go/internal/a2a" @@ -15,82 +19,159 @@ import ( "trpc.group/trpc-go/trpc-a2a-go/protocol" ) +var ( + serveAgentsTransport string + serveAgentsHost string + serveAgentsPort int +) + +var a2aContextBySessionAndAgent sync.Map + var ServeAgentsCmd = &cobra.Command{ Use: "serve-agents", Short: "Serve kagent agents via MCP", RunE: func(cmd *cobra.Command, args []string) error { + cfg, cfgErr := config.Get() s := mcpserver.NewMCPServer( "kagent-agents", version.Version, mcpserver.WithToolCapabilities(false), ) - if cfg, err := config.Get(); err == nil { - if resp, err := cfg.Client().Agent.ListAgents(cmd.Context()); err == nil { - for _, agent := range resp.Data { - if !agent.Accepted || !agent.DeploymentReady || agent.Agent == nil { - continue - } - toolName, agentNS, agentName := agent.ID, agent.Agent.Namespace, agent.Agent.Name - s.AddTool(mcp.NewTool(toolName, - mcp.WithDescription("kagent agent "+agentNS+"/"+agentName), - mcp.WithString("context_id", mcp.Description("A2A context ID")), - mcp.WithNumber("history_length", mcp.Description("Requested history length")), - mcp.WithString("task", mcp.Description("Task to run"), mcp.Required()), - ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - task, err := request.RequireString("task") - if err != nil { - return mcp.NewToolResultError(err.Error()), nil - } - contextID := request.GetString("context_id", "") - historyLength := request.GetInt("history_length", 0) - var contextIDPtr *string - if contextID != "" { - contextIDPtr = &contextID - } - var historyLengthPtr *int - if historyLength > 0 { - historyLengthPtr = &historyLength - } - a2aURL := fmt.Sprintf("%s/api/a2a/%s/%s", cfg.KAgentURL, agentNS, agentName) - client, err := a2aclient.NewA2AClient(a2aURL, a2aclient.WithTimeout(cfg.Timeout)) - if err != nil { - return mcp.NewToolResultErrorFromErr("a2a client", err), nil - } - params := protocol.SendMessageParams{ - Configuration: &protocol.SendMessageConfiguration{HistoryLength: historyLengthPtr}, - Message: protocol.Message{ - Kind: protocol.KindMessage, Role: protocol.MessageRoleUser, ContextID: contextIDPtr, Parts: []protocol.Part{protocol.NewTextPart(task)}, - }, - } - result, err := client.SendMessage(ctx, params) - if err != nil { - return mcp.NewToolResultErrorFromErr("a2a send", err), nil - } - var text string - switch a2aResult := result.Result.(type) { - case *protocol.Message: - text = a2a.ExtractText(*a2aResult) - case *protocol.Task: - if a2aResult.Status.Message != nil { - text = a2a.ExtractText(*a2aResult.Status.Message) - } - for _, artifact := range a2aResult.Artifacts { - text += a2a.ExtractText(protocol.Message{Parts: artifact.Parts}) - } - } - if text == "" { - raw, err := result.MarshalJSON() - if err != nil { - return mcp.NewToolResultErrorFromErr("marshal result", err), nil - } - text = string(raw) - } - return mcp.NewToolResultText(text), nil - }) + + s.AddTool(mcp.NewTool("list_agents", + mcp.WithDescription("List invokable kagent agents (accepted + deploymentReady)"), + ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if cfgErr != nil { + return mcp.NewToolResultErrorFromErr("config", cfgErr), nil + } + resp, err := cfg.Client().Agent.ListAgents(ctx) + if err != nil { + return mcp.NewToolResultErrorFromErr("list agents", err), nil + } + type agentSummary struct { + Ref string `json:"ref"` + ID string `json:"id"` + Description string `json:"description,omitempty"` + } + agents := make([]agentSummary, 0) + for _, agent := range resp.Data { + if !agent.Accepted || !agent.DeploymentReady || agent.Agent == nil { + continue + } + ref := agent.Agent.Namespace + "/" + agent.Agent.Name + agents = append(agents, agentSummary{Ref: ref, ID: agent.ID, Description: agent.Agent.Spec.Description}) + } + result, err := mcp.NewToolResultJSON(agents) + if err != nil { + return mcp.NewToolResultErrorFromErr("encode agents", err), nil + } + return result, nil + }) + + s.AddTool(mcp.NewTool("invoke_agent", + mcp.WithDescription("Invoke a kagent agent via A2A"), + mcp.WithString("agent", mcp.Description("Agent name (or namespace/name)"), mcp.Required()), + mcp.WithString("task", mcp.Description("Task to run"), mcp.Required()), + ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if cfgErr != nil { + return mcp.NewToolResultErrorFromErr("config", cfgErr), nil + } + agentRef, err := request.RequireString("agent") + if err != nil { + return mcp.NewToolResultError(err.Error()), nil + } + task, err := request.RequireString("task") + if err != nil { + return mcp.NewToolResultError(err.Error()), nil + } + agentNS, agentName, ok := strings.Cut(agentRef, "/") + if !ok { + agentNS, agentName = cfg.Namespace, agentRef + } + agentRef = agentNS + "/" + agentName + + sessionID := "unknown" + if session := mcpserver.ClientSessionFromContext(ctx); session != nil { + sessionID = session.SessionID() + } + contextKey := sessionID + "|" + agentRef + var contextIDPtr *string + if prior, ok := a2aContextBySessionAndAgent.Load(contextKey); ok { + if priorStr, ok := prior.(string); ok && priorStr != "" { + contextIDPtr = &priorStr + } + } + + a2aURL := fmt.Sprintf("%s/api/a2a/%s/%s", cfg.KAgentURL, agentNS, agentName) + client, err := a2aclient.NewA2AClient(a2aURL, a2aclient.WithTimeout(cfg.Timeout)) + if err != nil { + return mcp.NewToolResultErrorFromErr("a2a client", err), nil + } + result, err := client.SendMessage(ctx, protocol.SendMessageParams{Message: protocol.Message{ + Kind: protocol.KindMessage, Role: protocol.MessageRoleUser, ContextID: contextIDPtr, Parts: []protocol.Part{protocol.NewTextPart(task)}, + }}) + if err != nil { + return mcp.NewToolResultErrorFromErr("a2a send", err), nil + } + + var responseText, newContextID string + switch a2aResult := result.Result.(type) { + case *protocol.Message: + responseText = a2a.ExtractText(*a2aResult) + if a2aResult.ContextID != nil { + newContextID = *a2aResult.ContextID + } + case *protocol.Task: + newContextID = a2aResult.ContextID + if a2aResult.Status.Message != nil { + responseText = a2a.ExtractText(*a2aResult.Status.Message) } + for _, artifact := range a2aResult.Artifacts { + responseText += a2a.ExtractText(protocol.Message{Parts: artifact.Parts}) + } + } + if responseText == "" { + raw, err := result.MarshalJSON() + if err != nil { + return mcp.NewToolResultErrorFromErr("marshal result", err), nil + } + responseText = string(raw) + } + if newContextID != "" { + a2aContextBySessionAndAgent.Store(contextKey, newContextID) } + return mcp.NewToolResultStructured(map[string]any{ + "agent": agentRef, + "context_id": newContextID, + "text": responseText, + }, responseText), nil + }) + + switch strings.ToLower(serveAgentsTransport) { + case "stdio": + stdioServer := mcpserver.NewStdioServer(s) + return stdioServer.Listen(cmd.Context(), os.Stdin, os.Stdout) + case "http": + addr := fmt.Sprintf("%s:%d", serveAgentsHost, serveAgentsPort) + httpServer := mcpserver.NewStreamableHTTPServer(s) + go func() { + <-cmd.Context().Done() + shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + _ = httpServer.Shutdown(shutdownCtx) + }() + if err := httpServer.Start(addr); err != nil && err != http.ErrServerClosed { + return err + } + return nil + default: + return fmt.Errorf("invalid transport %q (expected stdio or http)", serveAgentsTransport) } - stdioServer := mcpserver.NewStdioServer(s) - return stdioServer.Listen(cmd.Context(), os.Stdin, os.Stdout) }, } + +func init() { + ServeAgentsCmd.Flags().StringVar(&serveAgentsTransport, "transport", "stdio", "Transport mode (stdio or http)") + ServeAgentsCmd.Flags().StringVar(&serveAgentsHost, "host", "127.0.0.1", "HTTP host to bind (when --transport http)") + ServeAgentsCmd.Flags().IntVar(&serveAgentsPort, "port", 3000, "HTTP port to bind (when --transport http)") +} From aeaa6e9a64b0027f926bc80049a0ecf3f9e7c7a6 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Tue, 13 Jan 2026 13:53:21 +0530 Subject: [PATCH 13/24] e2e: invoke agent via MCP serve-agents --- go/test/e2e/mcp_serve_agents_test.go | 133 +++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 go/test/e2e/mcp_serve_agents_test.go diff --git a/go/test/e2e/mcp_serve_agents_test.go b/go/test/e2e/mcp_serve_agents_test.go new file mode 100644 index 000000000..677e7be2e --- /dev/null +++ b/go/test/e2e/mcp_serve_agents_test.go @@ -0,0 +1,133 @@ +package e2e_test + +import ( + "bufio" + "bytes" + "context" + "encoding/json" + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestE2EInvokeAgentThroughMCPServeAgents(t *testing.T) { + kagentURL := os.Getenv("KAGENT_URL") + if kagentURL == "" { + kagentURL = "http://localhost:8083" + } + + _, testFile, _, ok := runtime.Caller(0) + require.True(t, ok) + goModuleRoot := filepath.Clean(filepath.Join(filepath.Dir(testFile), "../..")) + + kagentBin := filepath.Join(t.TempDir(), "kagent") + build := exec.Command("go", "build", "-o", kagentBin, "./cli/cmd/kagent") + build.Dir = goModuleRoot + buildOutput, err := build.CombinedOutput() + require.NoError(t, err, string(buildOutput)) + + homeDir := t.TempDir() + cfgDir := filepath.Join(homeDir, ".kagent") + require.NoError(t, os.MkdirAll(cfgDir, 0755)) + cfgPath := filepath.Join(cfgDir, "config.yaml") + require.NoError(t, os.WriteFile(cfgPath, []byte(fmt.Sprintf("kagent_url: %s\nnamespace: kagent\ntimeout: 300s\n", kagentURL)), 0644)) + + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + cmd := exec.CommandContext(ctx, kagentBin, "mcp", "serve-agents") + cmd.Env = append(os.Environ(), "HOME="+homeDir) + stdout, err := cmd.StdoutPipe() + require.NoError(t, err) + stdin, err := cmd.StdinPipe() + require.NoError(t, err) + var stderr bytes.Buffer + cmd.Stderr = &stderr + require.NoError(t, cmd.Start()) + t.Cleanup(func() { + _ = stdin.Close() + _ = cmd.Process.Kill() + _ = cmd.Wait() + }) + + lines := make(chan string, 32) + go func() { + scanner := bufio.NewScanner(stdout) + for scanner.Scan() { + lines <- scanner.Text() + } + close(lines) + }() + + writeLine := func(line string) { + _, _ = fmt.Fprintln(stdin, line) + } + + readResponse := func(wantID int) json.RawMessage { + deadline := time.NewTimer(15 * time.Second) + defer deadline.Stop() + for { + select { + case line, ok := <-lines: + require.True(t, ok, stderr.String()) + var msg struct { + ID int `json:"id"` + Result json.RawMessage `json:"result,omitempty"` + Error json.RawMessage `json:"error,omitempty"` + } + require.NoError(t, json.Unmarshal([]byte(line), &msg), line) + if msg.ID != wantID { + continue + } + require.Nil(t, msg.Error, line) + return msg.Result + case <-deadline.C: + t.Fatalf("timed out waiting for id=%d; stderr=%s", wantID, stderr.String()) + } + } + } + + writeLine(`{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"e2e","version":"0.0.0"}}}`) + _ = readResponse(1) + writeLine(`{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}`) + + writeLine(`{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}`) + toolsList := readResponse(2) + var listResult struct { + Tools []struct { + Name string `json:"name"` + } `json:"tools"` + } + require.NoError(t, json.Unmarshal(toolsList, &listResult), string(toolsList)) + require.GreaterOrEqual(t, len(listResult.Tools), 2) + toolNames := make([]string, 0, len(listResult.Tools)) + for _, tool := range listResult.Tools { + toolNames = append(toolNames, tool.Name) + } + require.Contains(t, toolNames, "list_agents") + require.Contains(t, toolNames, "invoke_agent") + + writeLine(`{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_agents"}}`) + agentsResult := readResponse(3) + var callResult struct { + Content []struct { + Type string `json:"type"` + Text string `json:"text"` + } `json:"content"` + } + require.NoError(t, json.Unmarshal(agentsResult, &callResult), string(agentsResult)) + require.NotEmpty(t, callResult.Content) + require.Contains(t, callResult.Content[0].Text, "kebab-agent") + + writeLine(`{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"invoke_agent","arguments":{"agent":"kebab-agent","task":"What can you do?"}}}`) + invokeResult := readResponse(4) + require.NoError(t, json.Unmarshal(invokeResult, &callResult), string(invokeResult)) + require.NotEmpty(t, callResult.Content) + require.Contains(t, callResult.Content[0].Text, "kebab") +} From c5b4c9d88239eabff3862afcff0aba8b4db5369b Mon Sep 17 00:00:00 2001 From: riturajFi Date: Wed, 14 Jan 2026 17:41:48 +0530 Subject: [PATCH 14/24] mcp: drop unused agent id from list_agents --- go/cli/internal/cli/mcp/serve_agents.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 148ca466c..14b2001b9 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -50,7 +50,6 @@ var ServeAgentsCmd = &cobra.Command{ } type agentSummary struct { Ref string `json:"ref"` - ID string `json:"id"` Description string `json:"description,omitempty"` } agents := make([]agentSummary, 0) @@ -59,7 +58,7 @@ var ServeAgentsCmd = &cobra.Command{ continue } ref := agent.Agent.Namespace + "/" + agent.Agent.Name - agents = append(agents, agentSummary{Ref: ref, ID: agent.ID, Description: agent.Agent.Spec.Description}) + agents = append(agents, agentSummary{Ref: ref, Description: agent.Agent.Spec.Description}) } result, err := mcp.NewToolResultJSON(agents) if err != nil { From 3fcef83b5b6f6ae4581320ebd1b69b75db2303a4 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Wed, 14 Jan 2026 17:43:34 +0530 Subject: [PATCH 15/24] mcp: fail fast when config is invalid --- go/cli/internal/cli/mcp/serve_agents.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 14b2001b9..3c0503830 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -31,7 +31,10 @@ var ServeAgentsCmd = &cobra.Command{ Use: "serve-agents", Short: "Serve kagent agents via MCP", RunE: func(cmd *cobra.Command, args []string) error { - cfg, cfgErr := config.Get() + cfg, err := config.Get() + if err != nil { + return fmt.Errorf("config: %w", err) + } s := mcpserver.NewMCPServer( "kagent-agents", version.Version, @@ -41,9 +44,6 @@ var ServeAgentsCmd = &cobra.Command{ s.AddTool(mcp.NewTool("list_agents", mcp.WithDescription("List invokable kagent agents (accepted + deploymentReady)"), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - if cfgErr != nil { - return mcp.NewToolResultErrorFromErr("config", cfgErr), nil - } resp, err := cfg.Client().Agent.ListAgents(ctx) if err != nil { return mcp.NewToolResultErrorFromErr("list agents", err), nil @@ -72,9 +72,6 @@ var ServeAgentsCmd = &cobra.Command{ mcp.WithString("agent", mcp.Description("Agent name (or namespace/name)"), mcp.Required()), mcp.WithString("task", mcp.Description("Task to run"), mcp.Required()), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - if cfgErr != nil { - return mcp.NewToolResultErrorFromErr("config", cfgErr), nil - } agentRef, err := request.RequireString("agent") if err != nil { return mcp.NewToolResultError(err.Error()), nil From 42c7809fe890dbeb860f821c3a1e3c932367e435 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Wed, 14 Jan 2026 17:44:22 +0530 Subject: [PATCH 16/24] mcp: avoid context collisions when session id missing --- go/cli/internal/cli/mcp/serve_agents.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 3c0503830..5559a5007 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -7,6 +7,7 @@ import ( "os" "strings" "sync" + "sync/atomic" "time" "github.com/kagent-dev/kagent/go/cli/internal/config" @@ -27,6 +28,8 @@ var ( var a2aContextBySessionAndAgent sync.Map +var fallbackInvocationCounter uint64 + var ServeAgentsCmd = &cobra.Command{ Use: "serve-agents", Short: "Serve kagent agents via MCP", @@ -86,9 +89,14 @@ var ServeAgentsCmd = &cobra.Command{ } agentRef = agentNS + "/" + agentName - sessionID := "unknown" + sessionID := "" if session := mcpserver.ClientSessionFromContext(ctx); session != nil { sessionID = session.SessionID() + } else if headerSessionID := request.Header.Get(mcpserver.HeaderKeySessionID); headerSessionID != "" { + sessionID = headerSessionID + } + if sessionID == "" { + sessionID = fmt.Sprintf("invocation-%d", atomic.AddUint64(&fallbackInvocationCounter, 1)) } contextKey := sessionID + "|" + agentRef var contextIDPtr *string From ccd0f5dfa98765de093c28a478ce167edba989c6 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Wed, 14 Jan 2026 17:44:53 +0530 Subject: [PATCH 17/24] mcp: log http server listen address --- go/cli/internal/cli/mcp/serve_agents.go | 1 + 1 file changed, 1 insertion(+) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 5559a5007..4170d5021 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -157,6 +157,7 @@ var ServeAgentsCmd = &cobra.Command{ return stdioServer.Listen(cmd.Context(), os.Stdin, os.Stdout) case "http": addr := fmt.Sprintf("%s:%d", serveAgentsHost, serveAgentsPort) + cmd.PrintErrf("MCP server listening on http://%s/mcp\n", addr) httpServer := mcpserver.NewStreamableHTTPServer(s) go func() { <-cmd.Context().Done() From 5257db261d02b716a3dfa3b29dc05b123960cdee Mon Sep 17 00:00:00 2001 From: riturajFi Date: Wed, 14 Jan 2026 17:45:45 +0530 Subject: [PATCH 18/24] mcp: cleanup stored contexts when sessions end --- go/cli/internal/cli/mcp/serve_agents.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index 4170d5021..ed89938cd 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -38,10 +38,25 @@ var ServeAgentsCmd = &cobra.Command{ if err != nil { return fmt.Errorf("config: %w", err) } + hooks := &mcpserver.Hooks{} + hooks.AddOnUnregisterSession(func(ctx context.Context, session mcpserver.ClientSession) { + sessionID := session.SessionID() + a2aContextBySessionAndAgent.Range(func(key, _ any) bool { + keyStr, ok := key.(string) + if !ok { + return true + } + if strings.HasPrefix(keyStr, sessionID+"|") { + a2aContextBySessionAndAgent.Delete(key) + } + return true + }) + }) s := mcpserver.NewMCPServer( "kagent-agents", version.Version, mcpserver.WithToolCapabilities(false), + mcpserver.WithHooks(hooks), ) s.AddTool(mcp.NewTool("list_agents", From 6e46d37b732a9c9ecbcd9f365e9907d5bb9d1475 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Wed, 14 Jan 2026 17:46:23 +0530 Subject: [PATCH 19/24] mcp: return structured list_agents result with text fallback --- go/cli/internal/cli/mcp/serve_agents.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_agents.go index ed89938cd..5b7447fa9 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_agents.go @@ -78,11 +78,23 @@ var ServeAgentsCmd = &cobra.Command{ ref := agent.Agent.Namespace + "/" + agent.Agent.Name agents = append(agents, agentSummary{Ref: ref, Description: agent.Agent.Spec.Description}) } - result, err := mcp.NewToolResultJSON(agents) - if err != nil { - return mcp.NewToolResultErrorFromErr("encode agents", err), nil + if len(agents) == 0 { + return mcp.NewToolResultStructured(agents, "No invokable agents found."), nil + } + + var fallbackText strings.Builder + for i, agent := range agents { + if i > 0 { + fallbackText.WriteByte('\n') + } + fallbackText.WriteString(agent.Ref) + if agent.Description != "" { + fallbackText.WriteString(" - ") + fallbackText.WriteString(agent.Description) + } } - return result, nil + + return mcp.NewToolResultStructured(agents, fallbackText.String()), nil }) s.AddTool(mcp.NewTool("invoke_agent", From e820e70e0202fba36a245ddcd42ba1e62e9a906c Mon Sep 17 00:00:00 2001 From: riturajFi Date: Wed, 14 Jan 2026 17:50:00 +0530 Subject: [PATCH 20/24] test: make mcp serve-agents e2e deterministic --- go/test/e2e/mcp_serve_agents_test.go | 15 +++++++-- .../e2e/mocks/invoke_mcp_serve_agents.json | 31 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 go/test/e2e/mocks/invoke_mcp_serve_agents.json diff --git a/go/test/e2e/mcp_serve_agents_test.go b/go/test/e2e/mcp_serve_agents_test.go index 677e7be2e..235f21be8 100644 --- a/go/test/e2e/mcp_serve_agents_test.go +++ b/go/test/e2e/mcp_serve_agents_test.go @@ -17,6 +17,17 @@ import ( ) func TestE2EInvokeAgentThroughMCPServeAgents(t *testing.T) { + // Setup mock server (so agent responses are deterministic and don't hit real LLMs) + baseURL, stopServer := setupMockServer(t, "mocks/invoke_mcp_serve_agents.json") + defer stopServer() + + // Setup Kubernetes resources for a known-good agent + cli := setupK8sClient(t, false) + modelCfg := setupModelConfig(t, cli, baseURL) + agent := setupAgentWithOptions(t, cli, modelCfg.Name, nil, AgentOptions{ + Name: "kebab-agent", + }) + kagentURL := os.Getenv("KAGENT_URL") if kagentURL == "" { kagentURL = "http://localhost:8083" @@ -123,9 +134,9 @@ func TestE2EInvokeAgentThroughMCPServeAgents(t *testing.T) { } require.NoError(t, json.Unmarshal(agentsResult, &callResult), string(agentsResult)) require.NotEmpty(t, callResult.Content) - require.Contains(t, callResult.Content[0].Text, "kebab-agent") + require.Contains(t, callResult.Content[0].Text, agent.Namespace+"/"+agent.Name) - writeLine(`{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"invoke_agent","arguments":{"agent":"kebab-agent","task":"What can you do?"}}}`) + writeLine(fmt.Sprintf(`{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"invoke_agent","arguments":{"agent":%q,"task":"What can you do?"}}}`, agent.Name)) invokeResult := readResponse(4) require.NoError(t, json.Unmarshal(invokeResult, &callResult), string(invokeResult)) require.NotEmpty(t, callResult.Content) diff --git a/go/test/e2e/mocks/invoke_mcp_serve_agents.json b/go/test/e2e/mocks/invoke_mcp_serve_agents.json new file mode 100644 index 000000000..efd569d28 --- /dev/null +++ b/go/test/e2e/mocks/invoke_mcp_serve_agents.json @@ -0,0 +1,31 @@ +{ + "openai": [ + { + "name": "serve_agents_request", + "match": { + "match_type": "contains", + "message": { + "content": "What can you do?", + "role": "user" + } + }, + "response": { + "id": "chatcmpl-1", + "object": "chat.completion", + "created": 1677652288, + "model": "gpt-4.1-mini", + "choices": [ + { + "index": 0, + "role": "assistant", + "message": { + "content": "I can answer questions and help you with tasks. Also: kebab.", + "role": "assistant" + }, + "finish_reason": "stop" + } + ] + } + } + ] +} From cf93df58b9cdbced146a13bc11578b2a5b3c600b Mon Sep 17 00:00:00 2001 From: riturajFi Date: Thu, 15 Jan 2026 12:02:14 +0530 Subject: [PATCH 21/24] minor refactor --- go/cli/internal/cli/mcp/{serve_agents.go => serve_mcp.go} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename go/cli/internal/cli/mcp/{serve_agents.go => serve_mcp.go} (99%) diff --git a/go/cli/internal/cli/mcp/serve_agents.go b/go/cli/internal/cli/mcp/serve_mcp.go similarity index 99% rename from go/cli/internal/cli/mcp/serve_agents.go rename to go/cli/internal/cli/mcp/serve_mcp.go index 5b7447fa9..24ed9a326 100644 --- a/go/cli/internal/cli/mcp/serve_agents.go +++ b/go/cli/internal/cli/mcp/serve_mcp.go @@ -31,7 +31,7 @@ var a2aContextBySessionAndAgent sync.Map var fallbackInvocationCounter uint64 var ServeAgentsCmd = &cobra.Command{ - Use: "serve-agents", + Use: "serve-mcp", Short: "Serve kagent agents via MCP", RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.Get() From a9928f07cbfa5496c3ba8177ccdc7b48fda555ed Mon Sep 17 00:00:00 2001 From: riturajFi Date: Sun, 18 Jan 2026 16:46:43 +0530 Subject: [PATCH 22/24] fix: minor fix --- go/test/e2e/invoke_api_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/e2e/invoke_api_test.go b/go/test/e2e/invoke_api_test.go index ddeda2156..f9f308ffb 100644 --- a/go/test/e2e/invoke_api_test.go +++ b/go/test/e2e/invoke_api_test.go @@ -518,7 +518,7 @@ func TestE2EInvokeDeclarativeAgentWithMcpServerTool(t *testing.T) { Kind: "MCPServer", Name: mcpServer.Name, }, - ToolNames: []string{"get-sum"}, + ToolNames: []string{"add"}, }, }, } From e8f2d72a6668d59d7bdcad8355184177199a3e45 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Sun, 18 Jan 2026 16:49:01 +0530 Subject: [PATCH 23/24] fix: minor fix --- go/test/e2e/invoke_api_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/test/e2e/invoke_api_test.go b/go/test/e2e/invoke_api_test.go index f9f308ffb..1de97e9a2 100644 --- a/go/test/e2e/invoke_api_test.go +++ b/go/test/e2e/invoke_api_test.go @@ -518,7 +518,7 @@ func TestE2EInvokeDeclarativeAgentWithMcpServerTool(t *testing.T) { Kind: "MCPServer", Name: mcpServer.Name, }, - ToolNames: []string{"add"}, + ToolNames: []string{"get-sum"}, }, }, } @@ -533,7 +533,7 @@ func TestE2EInvokeDeclarativeAgentWithMcpServerTool(t *testing.T) { // Run tests t.Run("sync_invocation", func(t *testing.T) { - runSyncTest(t, a2aClient, "add 3 and 5", "8", nil) + runSyncTest(t, a2aClient, "add 3 and 5. To add two numbers, call the tool named get-sum", "8", nil) }) t.Run("streaming_invocation", func(t *testing.T) { From be7aa78bcca8e2c48db18f6f25e103d97f459c19 Mon Sep 17 00:00:00 2001 From: riturajFi Date: Mon, 19 Jan 2026 10:53:33 +0530 Subject: [PATCH 24/24] test: signed commit --- go/test/e2e/invoke_api_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/e2e/invoke_api_test.go b/go/test/e2e/invoke_api_test.go index 1de97e9a2..7b37bd044 100644 --- a/go/test/e2e/invoke_api_test.go +++ b/go/test/e2e/invoke_api_test.go @@ -508,7 +508,7 @@ func TestE2EInvokeDeclarativeAgentWithMcpServerTool(t *testing.T) { // Setup Kubernetes client (include v1alpha1 for MCPServer) cli := setupK8sClient(t, true) mcpServer := setupMCPServer(t, cli) - // Define tools + // Define tools tools := []*v1alpha2.Tool{ { Type: v1alpha2.ToolProviderType_McpServer,