Add new 'network' transport mode that serves both HTTP and SSE protocols on the same port with different URL paths: - HTTP endpoint: /mcp - SSE endpoint: /sse Changes: - Add network mode to operation/operation.go using http.ServeMux routing - Update cmd/cmd.go flag descriptions to include network option - Update README.md with network mode documentation and examples - Update config.json with network mode configuration examples The network mode allows clients to choose between HTTP or SSE protocols without requiring separate server instances or ports. This provides better resource utilization and simpler deployment. Backward compatibility maintained - all existing modes (stdio, http, sse) work unchanged. Based on v0.3.0 for clean upstream compatibility.
91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
package operation
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"gitea.com/gitea/gitea-mcp/operation/issue"
|
|
"gitea.com/gitea/gitea-mcp/operation/pull"
|
|
"gitea.com/gitea/gitea-mcp/operation/repo"
|
|
"gitea.com/gitea/gitea-mcp/operation/search"
|
|
"gitea.com/gitea/gitea-mcp/operation/user"
|
|
"gitea.com/gitea/gitea-mcp/operation/version"
|
|
"gitea.com/gitea/gitea-mcp/pkg/flag"
|
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
|
|
|
"github.com/mark3labs/mcp-go/server"
|
|
)
|
|
|
|
var mcpServer *server.MCPServer
|
|
|
|
func RegisterTool(s *server.MCPServer) {
|
|
// User Tool
|
|
s.AddTools(user.Tool.Tools()...)
|
|
|
|
// Repo Tool
|
|
s.AddTools(repo.Tool.Tools()...)
|
|
|
|
// Issue Tool
|
|
s.AddTools(issue.Tool.Tools()...)
|
|
|
|
// Pull Tool
|
|
s.AddTools(pull.Tool.Tools()...)
|
|
|
|
// Search Tool
|
|
s.AddTools(search.Tool.Tools()...)
|
|
|
|
// Version Tool
|
|
s.AddTools(version.Tool.Tools()...)
|
|
|
|
s.DeleteTools("")
|
|
}
|
|
|
|
func Run() error {
|
|
mcpServer = newMCPServer(flag.Version)
|
|
RegisterTool(mcpServer)
|
|
switch flag.Mode {
|
|
case "stdio":
|
|
if err := server.ServeStdio(mcpServer); err != nil {
|
|
return err
|
|
}
|
|
case "sse":
|
|
sseServer := server.NewSSEServer(mcpServer)
|
|
log.Infof("Gitea MCP SSE server listening on :%d", flag.Port)
|
|
if err := sseServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil {
|
|
return err
|
|
}
|
|
case "http":
|
|
httpServer := server.NewStreamableHTTPServer(mcpServer)
|
|
log.Infof("Gitea MCP HTTP server listening on :%d", flag.Port)
|
|
if err := httpServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil {
|
|
return err
|
|
}
|
|
case "network":
|
|
// Network mode: serve both HTTP and SSE on same port with different URLs
|
|
streamableServer := server.NewStreamableHTTPServer(mcpServer)
|
|
sseServer := server.NewSSEServer(mcpServer)
|
|
|
|
// Create custom HTTP mux
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/mcp", streamableServer)
|
|
mux.Handle("/sse", sseServer)
|
|
|
|
// Start single HTTP server
|
|
log.Infof("Gitea MCP server listening on :%d (/mcp, /sse)", flag.Port)
|
|
return http.ListenAndServe(fmt.Sprintf(":%d", flag.Port), mux)
|
|
default:
|
|
return fmt.Errorf("invalid transport type: %s. Must be 'stdio', 'sse', 'http' or 'network'", flag.Mode)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func newMCPServer(version string) *server.MCPServer {
|
|
return server.NewMCPServer(
|
|
"Gitea MCP Server",
|
|
version,
|
|
server.WithToolCapabilities(true),
|
|
server.WithLogging(),
|
|
server.WithRecovery(),
|
|
)
|
|
}
|