Add channel management feature with public/private channels, membership (owner/member roles), invitations, broadcast messaging, and full MCP tool exposure. New files: - internal/channels/ - types, store, service, validation, errors - internal/mcp/channel_tools.go - 8 MCP tools for channel operations - schema/002_channels.sql - migration for channel_invites table MCP tools: create_channel, join_channel, leave_channel, list_channels, invite_to_channel, kick_from_channel, send_channel_message, update_channel Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
90 lines
2.3 KiB
Go
90 lines
2.3 KiB
Go
package mcp
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
"github.com/mark3labs/mcp-go/server"
|
|
|
|
"github.com/smart-mcp-proxy/synapbus/internal/agents"
|
|
"github.com/smart-mcp-proxy/synapbus/internal/channels"
|
|
"github.com/smart-mcp-proxy/synapbus/internal/messaging"
|
|
)
|
|
|
|
// MCPServer wraps the mcp-go server with SynapBus services.
|
|
type MCPServer struct {
|
|
mcpServer *server.MCPServer
|
|
sseServer *server.SSEServer
|
|
connMgr *ConnectionManager
|
|
agentService *agents.AgentService
|
|
logger *slog.Logger
|
|
}
|
|
|
|
// NewMCPServer creates and configures a new MCP server with all tools registered.
|
|
func NewMCPServer(
|
|
msgService *messaging.MessagingService,
|
|
agentService *agents.AgentService,
|
|
channelService *channels.Service,
|
|
) *MCPServer {
|
|
logger := slog.Default().With("component", "mcp-server")
|
|
|
|
// Create the mcp-go server
|
|
mcpSrv := server.NewMCPServer(
|
|
"SynapBus",
|
|
"0.1.0",
|
|
server.WithToolCapabilities(true),
|
|
)
|
|
|
|
// Register all tools
|
|
registrar := NewToolRegistrar(msgService, agentService)
|
|
registrar.RegisterAll(mcpSrv)
|
|
|
|
// Register channel tools
|
|
if channelService != nil {
|
|
channelRegistrar := NewChannelToolRegistrar(channelService)
|
|
channelRegistrar.RegisterAll(mcpSrv)
|
|
}
|
|
|
|
// Create SSE transport with context func for auth propagation
|
|
sseServer := server.NewSSEServer(mcpSrv,
|
|
server.WithSSEContextFunc(func(ctx context.Context, r *http.Request) context.Context {
|
|
// Propagate agent identity from HTTP auth to MCP context
|
|
if agent, ok := agents.AgentFromContext(r.Context()); ok {
|
|
return ContextWithAgentName(ctx, agent.Name)
|
|
}
|
|
return ctx
|
|
}),
|
|
)
|
|
|
|
s := &MCPServer{
|
|
mcpServer: mcpSrv,
|
|
sseServer: sseServer,
|
|
connMgr: NewConnectionManager(),
|
|
agentService: agentService,
|
|
logger: logger,
|
|
}
|
|
|
|
logger.Info("MCP server initialized")
|
|
return s
|
|
}
|
|
|
|
// SSEHandler returns the SSE handler for mounting on a router.
|
|
func (s *MCPServer) SSEHandler() http.Handler {
|
|
return s.sseServer
|
|
}
|
|
|
|
// ConnectionManager returns the connection manager.
|
|
func (s *MCPServer) ConnectionManager() *ConnectionManager {
|
|
return s.connMgr
|
|
}
|
|
|
|
// Shutdown gracefully shuts down the MCP server.
|
|
func (s *MCPServer) Shutdown(ctx context.Context) error {
|
|
s.logger.Info("MCP server shutting down")
|
|
if err := s.sseServer.Shutdown(ctx); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|