Skip to content

Conversation

@supreme-gg-gg
Copy link
Contributor

@supreme-gg-gg supreme-gg-gg commented Jan 14, 2026

The previous PR #1201 adds a CLI option to serve A2A agents via stdio / http transport MCP server. This PR extends this feature to the Go controller's HTTP server by adding a new /mcp route and handler for Streamable HTTP server. The MCP bridge exposes the list_agents and invoke_agent tools.

e2e test has been added using a MCP client. Manual verification was done using MCP inspector and MCP clients like Cursor as well.

This PR also migrates all usages of mark3labs/mcp-go to the new official go-sdk library from Anthropic for MCP protocol and server / client implementation. Most changes are direct and syntax-only. The only exception is that I cannot find a built-in option to set headers for transport interfaces (SSE/Streamable HTTP) in go-sdk, so I had to create a custom HTTP client to make sure these headers are set in reconciler.go

Copilot AI review requested due to automatic review settings January 14, 2026 17:58
@supreme-gg-gg supreme-gg-gg linked an issue Jan 14, 2026 that may be closed by this pull request
3 tasks
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the MCP server functionality to the Go controller's HTTP server by exposing A2A agents via a new /api/mcp endpoint. The implementation builds on PR #1201 which added CLI-based MCP serving, now bringing the same capabilities to the HTTP server with support for streamable HTTP transport.

Changes:

  • Added MCP handler bridging MCP protocol to A2A endpoints with session-based context management
  • Integrated MCP handler into HTTP server with new /api/mcp route
  • Added comprehensive E2E tests for MCP endpoint functionality including agent listing, invocation, and error handling

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
go/internal/mcp/mcp_handler.go Implements MCP-to-A2A bridge with list_agents and invoke_agent tools, session management, and context tracking
go/pkg/app/app.go Instantiates MCP handler and wires it into the HTTP server configuration
go/internal/httpserver/server.go Adds /api/mcp route and conditionally mounts MCP handler
go/test/e2e/invoke_mcp_test.go E2E tests validating MCP endpoint with agent listing, invocation, and error handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@EItanya EItanya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overally looks good to me, just some minor changes

APIPathMemories = "/api/memories"
APIPathNamespaces = "/api/namespaces"
APIPathA2A = "/api/a2a"
APIPathMCP = "/api/mcp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically the path for streamable HTTP mcp servers is /mcp, any reason we can't do that?

httpServer *mcpserver.StreamableHTTPServer
lock sync.RWMutex
// Map to store context IDs per session and agent
contextBySessionAndAgent sync.Map
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth adding a TODO that this will not work across replicas. We may be able to store any necessary data in an external store if need be. Not sure we have any data specific to MCP here though, since the A2A data is already stored.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This map is only for session "routing" so the agent using this MCP tool will have proper conversation continuation with the A2A agent by tracking the MCP context ID and the A2A context ID.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this session caching map since it won't work across replicas. The same functionality is achieved by just returning the context ID to the MCP client and most agents using it are capable of remembering the proper context id to call the A2A agent if it wants to continue the conversation. This makes the code simpler and avoids needing storage on server side.

@supreme-gg-gg
Copy link
Contributor Author

Overally looks good to me, just some minor changes

Yes the changes make sense, I haven't had the time to update them will do that now

Signed-off-by: Jet Chiang <pokyuen.jetchiang-ext@solo.io>
Signed-off-by: Jet Chiang <pokyuen.jetchiang-ext@solo.io>
Signed-off-by: Jet Chiang <pokyuen.jetchiang-ext@solo.io>
@supreme-gg-gg supreme-gg-gg changed the title feat: expose a2a agents via mcp in controller http server feat: expose a2a agents via mcp in controller http server and migrate to mcp go-sdk Jan 16, 2026
@supreme-gg-gg supreme-gg-gg requested a review from Copilot January 16, 2026 23:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

s.router.PathPrefix(APIPathMCP).Handler(s.config.MCPHandler)
}

// Use middleware for common functionality
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MCP handler route is registered before the authentication middleware is applied (line 237). In gorilla/mux, middleware added via Use() applies to routes registered before the Use() call, but the order can be confusing. While the current code appears correct (middleware applies to all routes including MCP), this pattern is fragile. Consider either: (1) explicitly documenting that routes must be registered before middleware, or (2) applying middleware before route registration for clarity and to prevent future security issues.

Suggested change
// Use middleware for common functionality
// Use middleware for common functionality.
//
// NOTE: gorilla/mux applies middleware added via Use() to all routes
// registered on this router, including those registered *before* the Use()
// call. To avoid confusion and potential security issues where routes might
// accidentally be registered without authentication, all routes for this
// server MUST be registered above this middleware block. Do not add new
// routes below these Use() calls.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +28
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context with timeout is created and immediately deferred for cancellation, but then the session remains open beyond this function's scope via t.Cleanup. This means the context expires after 30 seconds while the session might still be in use. Consider using the test's context or removing the timeout to avoid premature context cancellation during test execution.

Copilot uses AI. Check for mistakes.
supreme-gg-gg and others added 2 commits January 16, 2026 18:41
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Jet Chiang <jetjiang.ez@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Jet Chiang <jetjiang.ez@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] expose kagent agents through MCP

2 participants