Skip to content

Commit 74387dd

Browse files
authored
fix(mcp): apply shared gqlgen extensions to MCP executor (#84)
* fix(mcp): apply shared gqlgen extensions to MCP executor The MCP path used a bare executor, bypassing the extensions registered on the HTTP GraphQL server: complexity limit, introspection, metrics tracer, and the error presenter. configureGQLExtensions now holds the single shared list and is applied to both *handler.Server and *executor.Executor via server-garage v0.4.0's ExecutorOption hook. Bumps server-garage v0.1.1 -> v0.4.0. * ci: pin golangci-lint to v2.12.1 Unpinned 'latest' pulls v2.12.2, whose release artifact fails the installer's sha256 verification, breaking CI. Matches the pin in telemetry-api and server-garage.
1 parent 12d064b commit 74387dd

4 files changed

Lines changed: 29 additions & 7 deletions

File tree

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ VERSION := $(shell git describe --tags || echo "v0.0.0")
1919
VER_CUT := $(shell echo $(VERSION) | cut -c2-)
2020

2121
# Dependency versions
22-
GOLANGCI_VERSION = latest
22+
GOLANGCI_VERSION = v2.12.1
2323
PROTOC_VERSION = 33.4
2424
PROTOC_GEN_GO_VERSION = $(shell go list -m -f '{{.Version}}' google.golang.org/protobuf)
2525
PROTOC_GEN_GO_GRPC_VERSION = v1.5.1
@@ -78,7 +78,7 @@ podman-push-multiarch:
7878

7979
tools-golangci-lint: ## install golangci-lint
8080
@mkdir -p $(PATHINSTBIN)
81-
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | BINARY=golangci-lint bash -s -- ${GOLANGCI_VERSION}
81+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_VERSION)/install.sh | sh -s -- -b $(PATHINSTBIN) $(GOLANGCI_VERSION)
8282

8383
tools-protoc: ## install protoc
8484
@mkdir -p $(PATHINSTBIN)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/ClickHouse/clickhouse-go/v2 v2.43.0
88
github.com/DIMO-Network/clickhouse-infra v0.0.7
99
github.com/DIMO-Network/cloudevent v0.2.9
10-
github.com/DIMO-Network/server-garage v0.1.1
10+
github.com/DIMO-Network/server-garage v0.4.0
1111
github.com/DIMO-Network/shared v1.1.7
1212
github.com/DIMO-Network/token-exchange-api v0.4.0
1313
github.com/auth0/go-jwt-middleware/v2 v2.2.2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ github.com/DIMO-Network/clickhouse-infra v0.0.7 h1:TAsjkFFKu3D5Xg6dwBcRBryjCVSlX
1818
github.com/DIMO-Network/clickhouse-infra v0.0.7/go.mod h1:XS80lhSJNWBWGgZ+m4j7++zFj1wAXfmtV2gJfhGlabQ=
1919
github.com/DIMO-Network/cloudevent v0.2.9 h1:8MxbZtNReMHbwPUGQc2+G5THf08dFxju+npKZFZygJc=
2020
github.com/DIMO-Network/cloudevent v0.2.9/go.mod h1:I/9NcpMozV5Fw194WimhbkAsJtKVZf5UKYJ9hgc8Cdg=
21-
github.com/DIMO-Network/server-garage v0.1.1 h1:EYmyy+Fgi2BNW0Bufn04BViDtb8BCWaN7C7BbEuoI5s=
22-
github.com/DIMO-Network/server-garage v0.1.1/go.mod h1:Z3A1KDUsXey+XhrPhmw/wyCidfrQvmEdWp7nShno7ZM=
21+
github.com/DIMO-Network/server-garage v0.4.0 h1:3ukXvtldIhLldn9AtbtQBooBjT2gicvB3WphrsjNQho=
22+
github.com/DIMO-Network/server-garage v0.4.0/go.mod h1:Z3A1KDUsXey+XhrPhmw/wyCidfrQvmEdWp7nShno7ZM=
2323
github.com/DIMO-Network/shared v1.1.7 h1:5Ex8bZ6BpOjcLj4u7n5Kih1Ho6b9BVJsKpKn4iU2EaM=
2424
github.com/DIMO-Network/shared v1.1.7/go.mod h1:lDHUKwwT2LW6Zvd42Nb33dXklRNTmfyOlbUNx2dQfGY=
2525
github.com/DIMO-Network/token-exchange-api v0.4.0 h1:EayDrw9VdyAfc6rbpdnDxFhlN3lMhbonUJoouKZu35g=

internal/app/app.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"net/http"
66
"github.com/99designs/gqlgen/graphql"
7+
"github.com/99designs/gqlgen/graphql/executor"
78
"github.com/99designs/gqlgen/graphql/handler"
89
"github.com/99designs/gqlgen/graphql/handler/extension"
910
"github.com/99designs/gqlgen/graphql/handler/transport"
@@ -86,7 +87,13 @@ func New(settings config.Settings) (*App, error) {
8687

8788
serverHandler := authChain(gqlSrv)
8889

89-
mcpHandler, err := mcpserver.New(mcpserver.NewGQLGenExecutor(es), "DIMO Fetch", "0.1.0", "fetch",
90+
// The MCP executor gets the same extension set as the HTTP GraphQL server
91+
// so tool calls are complexity-limited, traced, and error-shaped identically.
92+
mcpExec := mcpserver.NewGQLGenExecutor(es, func(e *executor.Executor) {
93+
configureGQLExtensions(e)
94+
})
95+
96+
mcpHandler, err := mcpserver.New(mcpExec, "DIMO Fetch", "0.1.0", "fetch",
9097
mcpserver.WithTools(graph.MCPTools),
9198
mcpserver.WithCondensedSchema(graph.CondensedSchema),
9299
)
@@ -124,11 +131,26 @@ func newGraphQLHandler(es graphql.ExecutableSchema) *handler.Server {
124131
srv.AddTransport(transport.Options{})
125132
srv.AddTransport(transport.GET{})
126133
srv.AddTransport(transport.POST{})
134+
configureGQLExtensions(srv)
135+
return srv
136+
}
137+
138+
// gqlExtensionTarget is satisfied by both *handler.Server and
139+
// *executor.Executor, letting the HTTP GraphQL server and the MCP executor
140+
// share one extension configuration.
141+
type gqlExtensionTarget interface {
142+
Use(graphql.HandlerExtension)
143+
SetErrorPresenter(graphql.ErrorPresenterFunc)
144+
}
145+
146+
// configureGQLExtensions applies the extension set shared by the HTTP GraphQL
147+
// server and the MCP executor: introspection, complexity limit, metrics, and
148+
// error shaping.
149+
func configureGQLExtensions(srv gqlExtensionTarget) {
127150
srv.Use(extension.Introspection{})
128151
srv.Use(extension.FixedComplexityLimit(100))
129152
srv.Use(gqlmetrics.Tracer{})
130153
srv.SetErrorPresenter(errorhandler.ErrorPresenter)
131-
return srv
132154
}
133155

134156
// CreateGRPCServer creates a new gRPC server with the given logger and settings.

0 commit comments

Comments
 (0)