Skip to content

Commit 8013efd

Browse files
author
Harshil Goel
authored
feat(core): Add mcp server (#9389)
Added an MCP server. To access it, add the following to your MCP config: ``` { "mcpServers": { "dgraph-binary": { "command": "/home/harshil/gopath/bin/dgraph", "args": ["mcp"] }, "dgraph-mcp": { "serverUrl": "http://localhost:8080/mcp/sse" }, "dgraph-mcp-ro": { "serverUrl": "http://localhost:8080/mcp-ro/sse" } } } ```
1 parent c5cdaf0 commit 8013efd

File tree

8 files changed

+711
-4
lines changed

8 files changed

+711
-4
lines changed

dgraph/cmd/alpha/run.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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,

dgraph/cmd/mcp/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Dgraph MCP (Master Control Protocol)
2+
3+
## Project Overview
4+
5+
This is a Dgraph-based Master Control Protocol (MCP) designed to provide advanced graph database
6+
management and querying capabilities. There are two ways you can access the mcp server:
7+
8+
1. Using the dgraph alpha's http endpoint
9+
2. Using the go code
10+
11+
## Key Components
12+
13+
- Dgraph schema management
14+
- Advanced data querying
15+
- Flexible graph database interactions
16+
17+
## Setup Instructions for dgraph alpha
18+
19+
- Install dgraph alpha
20+
- Start dgraph alpha
21+
22+
For Read only:
23+
24+
```json
25+
{
26+
"dgraph-mcp-ro": {
27+
"serverUrl": "http://localhost:8080/mcp-ro/sse"
28+
}
29+
}
30+
```
31+
32+
For Read write:
33+
34+
```json
35+
{
36+
"dgraph-mcp": {
37+
"serverUrl": "http://localhost:8080/mcp/sse"
38+
}
39+
}
40+
```
41+
42+
## Setup Instructions for go code
43+
44+
- Install dgraph binary
45+
- Insert the following to your mcp config:
46+
47+
```json
48+
{
49+
"mcpServers": {
50+
"dgraph": {
51+
"command": "dgraph_binary",
52+
"args": ["mcp", "-c", "dgraph://localhost:9080"]
53+
}
54+
}
55+
}
56+
```
57+
58+
- Modify the server details using args in dgraph mcp command
59+
60+
### Local Setup for Claude Desktop
61+
62+
You can setup a local experience using Claude app
63+
64+
Install Claude.app from https://claude.ai/download.
65+
66+
On Mac OS the configurations files are in `~/Library/Application\ Support/Claude`. Create
67+
`~/Library/Application\ Support/Claude/claude_desktop_config.json` file and set the content with mcp
68+
config shown above.
69+
70+
Close the Claude app and reopen it.
71+
72+
Check that the tools are listed in Claude desktop (Click on the tools icon).
73+
74+
You are ready to chat and get things done in Dgraph from Claude.
75+
76+
## Troubleshooting
77+
78+
- Check Dgraph connection settings
79+
- Verify Go module dependencies
80+
- Review error logs carefully

0 commit comments

Comments
 (0)