Skip to content

Commit d3e885d

Browse files
committed
Support Redis as session store
1 parent 1c2470b commit d3e885d

File tree

19 files changed

+270
-128
lines changed

19 files changed

+270
-128
lines changed

cmd/server.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cmd
22

33
import (
44
"log"
5+
"os"
56

67
"github.com/mark3labs/mcp-go/server"
78
"github.com/render-oss/render-mcp-server/pkg/cfg"
@@ -36,7 +37,17 @@ func Serve(transport string) *server.MCPServer {
3637
s.AddTools(logs.Tools(c)...)
3738

3839
if transport == "http" {
39-
sessionStore := session.NewInMemoryStore()
40+
var sessionStore session.Store
41+
if redisURL, ok := os.LookupEnv("REDIS_URL"); ok {
42+
log.Print("using Redis session store\n")
43+
sessionStore, err = session.NewRedisStore(redisURL)
44+
if err != nil {
45+
log.Fatalf("failed to initialize Redis session store: %v", err)
46+
}
47+
} else {
48+
log.Print("using in-memory session store\n")
49+
sessionStore = session.NewInMemoryStore()
50+
}
4051
if err := server.NewStreamableHTTPServer(s, server.WithHTTPContextFunc(session.ContextWithHTTPSession(sessionStore))).Start(":10000"); err != nil {
4152
log.Fatalf("Starting Streamable server: %v\n:", err)
4253
}

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,30 @@ module github.com/render-oss/render-mcp-server
33
go 1.24.1
44

55
require (
6+
github.com/alicebob/miniredis/v2 v2.35.0
67
github.com/jackc/pgx/v5 v5.7.5
78
github.com/mark3labs/mcp-go v0.32.0
9+
github.com/mitchellh/mapstructure v1.5.0
810
github.com/oapi-codegen/runtime v1.1.1
11+
github.com/redis/go-redis/v9 v9.10.0
912
github.com/spf13/pflag v1.0.6
1013
github.com/stretchr/testify v1.10.0
1114
gopkg.in/yaml.v3 v3.0.1
1215
)
1316

1417
require (
1518
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
19+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
1620
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
21+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
1722
github.com/google/uuid v1.6.0 // indirect
1823
github.com/jackc/pgpassfile v1.0.0 // indirect
1924
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
2025
github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2 // indirect
2126
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
2227
github.com/spf13/cast v1.9.2 // indirect
2328
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
29+
github.com/yuin/gopher-lua v1.1.1 // indirect
2430
golang.org/x/crypto v0.39.0 // indirect
2531
golang.org/x/mod v0.25.0 // indirect
2632
golang.org/x/sync v0.15.0 // indirect

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
2+
github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI=
3+
github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM=
24
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
35
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
46
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
7+
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
8+
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
9+
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
10+
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
11+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
12+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
513
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
614
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
715
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
16+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
17+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
818
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
919
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
1020
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
@@ -28,13 +38,17 @@ github.com/mark3labs/mcp-go v0.32.0 h1:fgwmbfL2gbd67obg57OfV2Dnrhs1HtSdlY/i5fn7M
2838
github.com/mark3labs/mcp-go v0.32.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
2939
github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2 h1:yVCLo4+ACVroOEr4iFU1iH46Ldlzz2rTuu18Ra7M8sU=
3040
github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2/go.mod h1:VzB2VoMh1Y32/QqDfg9ZJYHj99oM4LiGtqPZydTiQSQ=
41+
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
42+
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
3143
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
3244
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
3345
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
3446
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
3547
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3648
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
3749
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
50+
github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs=
51+
github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
3852
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
3953
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
4054
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
@@ -51,6 +65,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
5165
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
5266
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
5367
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
68+
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
69+
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
5470
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
5571
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
5672
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=

pkg/keyvalue/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func NewRepo(c keyValueRepoClient) *Repo {
2727
}
2828

2929
func (r *Repo) ListKeyValue(ctx context.Context, params *client.ListKeyValueParams) ([]*client.KeyValue, error) {
30-
workspace, err := session.FromContext(ctx).GetWorkspace()
30+
workspace, err := session.FromContext(ctx).GetWorkspace(ctx)
3131
if err != nil {
3232
return nil, err
3333
}

pkg/keyvalue/tools.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func createKeyValue(keyValueRepo *Repo) server.ServerTool {
126126
return mcp.NewToolResultError(err.Error()), nil
127127
}
128128

129-
ownerId, err := session.FromContext(ctx).GetWorkspace()
129+
ownerId, err := session.FromContext(ctx).GetWorkspace(ctx)
130130
if err != nil {
131131
return mcp.NewToolResultError(err.Error()), nil
132132
}

pkg/logs/tools.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func listLogs(logRepo *LogRepo) server.ServerTool {
114114
),
115115
),
116116
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
117-
ownerId, err := session.FromContext(ctx).GetWorkspace()
117+
ownerId, err := session.FromContext(ctx).GetWorkspace(ctx)
118118
if err != nil {
119119
return mcp.NewToolResultError(err.Error()), nil
120120
}
@@ -324,7 +324,7 @@ func listLogLabelValues(logRepo *LogRepo) server.ServerTool {
324324
return mcp.NewToolResultError(err.Error()), nil
325325
}
326326

327-
ownerId, err := session.FromContext(ctx).GetWorkspace()
327+
ownerId, err := session.FromContext(ctx).GetWorkspace(ctx)
328328
if err != nil {
329329
return mcp.NewToolResultError(err.Error()), nil
330330
}

pkg/owner/tools.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func listWorkspaces(ownerRepo *Repo) server.ServerTool {
4848
resultText := ""
4949

5050
if len(workspaces) == 1 {
51-
err = session.FromContext(ctx).SetWorkspace(workspaces[0].Id)
51+
err = session.FromContext(ctx).SetWorkspace(ctx, workspaces[0].Id)
5252
if err != nil {
5353
return mcp.NewToolResultError(err.Error()), nil
5454
}
@@ -84,7 +84,7 @@ func selectWorkspace() server.ServerTool {
8484
return mcp.NewToolResultError(err.Error()), nil
8585
}
8686

87-
err = session.FromContext(ctx).SetWorkspace(ownerID)
87+
err = session.FromContext(ctx).SetWorkspace(ctx, ownerID)
8888
if err != nil {
8989
return mcp.NewToolResultError(err.Error()), nil
9090
}
@@ -106,7 +106,7 @@ func getSelectedWorkspace() server.ServerTool {
106106
}),
107107
),
108108
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
109-
workspace, err := session.FromContext(ctx).GetWorkspace()
109+
workspace, err := session.FromContext(ctx).GetWorkspace(ctx)
110110
if err != nil {
111111
return mcp.NewToolResultError(err.Error()), nil
112112
}

pkg/postgres/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func NewRepo(c postgresRepoClient) *Repo {
2929
}
3030

3131
func (r *Repo) ListPostgres(ctx context.Context, params *client.ListPostgresParams) ([]*client.Postgres, error) {
32-
workspace, err := session.FromContext(ctx).GetWorkspace()
32+
workspace, err := session.FromContext(ctx).GetWorkspace(ctx)
3333
if err != nil {
3434
return nil, err
3535
}

pkg/postgres/tools.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func createPostgres(postgresRepo *Repo) server.ServerTool {
133133
return mcp.NewToolResultError(err.Error()), nil
134134
}
135135

136-
ownerId, err := session.FromContext(ctx).GetWorkspace()
136+
ownerId, err := session.FromContext(ctx).GetWorkspace(ctx)
137137
if err != nil {
138138
return mcp.NewToolResultError(err.Error()), nil
139139
}

pkg/service/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func NewRepo(c serviceRepoClient) *Repo {
3030
}
3131

3232
func (s *Repo) ListServices(ctx context.Context, params *client.ListServicesParams) ([]*client.Service, error) {
33-
workspace, err := session.FromContext(ctx).GetWorkspace()
33+
workspace, err := session.FromContext(ctx).GetWorkspace(ctx)
3434
if err != nil {
3535
return nil, err
3636
}

0 commit comments

Comments
 (0)