@@ -25,6 +25,7 @@ import (
2525 "time"
2626
2727 "github.com/golang/glog"
28+ "github.com/mark3labs/mcp-go/server"
2829 "github.com/pkg/errors"
2930 "github.com/spf13/cobra"
3031 "go.opencensus.io/plugin/ocgrpc"
@@ -42,6 +43,7 @@ import (
4243 _ "github.com/dgraph-io/gqlparser/v2/validator/rules" // make gql validator init() all rules
4344 "github.com/dgraph-io/ristretto/v2/z"
4445 "github.com/hypermodeinc/dgraph/v25/audit"
46+ "github.com/hypermodeinc/dgraph/v25/dgraph/cmd/mcp"
4547 "github.com/hypermodeinc/dgraph/v25/edgraph"
4648 "github.com/hypermodeinc/dgraph/v25/graphql/admin"
4749 "github.com/hypermodeinc/dgraph/v25/posting"
@@ -111,6 +113,8 @@ they form a Raft group and provide synchronous replication.
111113 flag .String ("custom_tokenizers" , "" ,
112114 "Comma separated list of tokenizer plugins for custom indices." )
113115
116+ flag .Bool ("mcp" , false , "run MCP server along with alpha." )
117+
114118 // By default Go GRPC traces all requests.
115119 grpc .EnableTracing = false
116120
@@ -472,9 +476,27 @@ func serveGRPC(l net.Listener, tlsCfg *tls.Config, closer *z.Closer) {
472476 s .Stop ()
473477}
474478
475- func setupServer (closer * z.Closer ) {
476- go worker .RunServer (bindall ) // For pb.communication.
479+ func setupMcp (baseMux * http.ServeMux , connectionString , url string , readOnly bool ) error {
480+ s , err := mcp .NewMCPServer (connectionString , readOnly )
481+ if err != nil {
482+ glog .Errorf ("Failed to initialize MCPServer: %v" , err )
483+ return err
484+ }
485+
486+ sse := server .NewSSEServer (s ,
487+ server .WithBasePath (url ),
488+ )
489+ baseMux .HandleFunc (url , sse .ServeHTTP )
490+ baseMux .HandleFunc (url + "/" , sse .ServeHTTP )
491+ return nil
492+ }
493+
494+ func buildConnectionString (addr string , port int ) string {
495+ return fmt .Sprintf ("dgraph://%s:%d" , addr , port )
496+ }
477497
498+ func setupServer (closer * z.Closer , enableMcp bool ) {
499+ go worker .RunServer (bindall ) // For pb.communication.
478500 laddr := "localhost"
479501 if bindall {
480502 laddr = "0.0.0.0"
@@ -576,6 +598,16 @@ func setupServer(closer *z.Closer) {
576598 // Initialize the servers.
577599 x .ServerCloser .AddRunning (3 )
578600 go serveGRPC (grpcListener , tlsCfg , x .ServerCloser )
601+
602+ if enableMcp {
603+ if err := setupMcp (baseMux , buildConnectionString (laddr , grpcPort ()), "/mcp" , false ); err != nil {
604+ log .Fatal (err )
605+ }
606+ if err := setupMcp (baseMux , buildConnectionString (laddr , grpcPort ()), "/mcp-ro" , true ); err != nil {
607+ log .Fatal (err )
608+ }
609+ }
610+
579611 go x .StartListenHttpAndHttps (httpListener , tlsCfg , x .ServerCloser )
580612
581613 go func () {
@@ -641,6 +673,8 @@ func run() {
641673 x .Config .Limit = z .NewSuperFlag (Alpha .Conf .GetString ("limit" )).MergeAndCheckDefault (
642674 worker .LimitDefaults )
643675
676+ enableMcp := Alpha .Conf .GetBool ("mcp" )
677+
644678 opts := worker.Options {
645679 PostingDir : Alpha .Conf .GetString ("postings" ),
646680 WALDir : Alpha .Conf .GetString ("wal" ),
@@ -821,7 +855,7 @@ func run() {
821855 // close alpha. This closer is for closing and waiting that subscription.
822856 adminCloser := z .NewCloser (1 )
823857
824- setupServer (adminCloser )
858+ setupServer (adminCloser , enableMcp )
825859 glog .Infoln ("GRPC and HTTP stopped." )
826860
827861 // This might not close until group is given the signal to close. So, only signal here,
0 commit comments