1
1
//! Execute GraphQL operations from an MCP tool
2
2
3
+ use std:: sync:: LazyLock ;
4
+
3
5
use crate :: errors:: McpError ;
4
6
use crate :: generated:: telemetry:: { TelemetryAttribute , TelemetryMetric } ;
5
7
use crate :: meter;
6
8
use opentelemetry:: KeyValue ;
7
9
use reqwest:: header:: { HeaderMap , HeaderValue } ;
8
- use reqwest_middleware:: { ClientBuilder , Extension } ;
10
+ use reqwest_middleware:: { ClientBuilder , ClientWithMiddleware , Extension } ;
9
11
use reqwest_tracing:: { OtelName , TracingMiddleware } ;
10
12
use rmcp:: model:: { CallToolResult , Content , ErrorCode } ;
11
13
use serde_json:: { Map , Value } ;
@@ -24,6 +26,13 @@ pub struct OperationDetails {
24
26
pub operation_name : Option < String > ,
25
27
}
26
28
29
+ static GRAPHQL_CLIENT : LazyLock < ClientWithMiddleware > = LazyLock :: new ( || {
30
+ ClientBuilder :: new ( reqwest:: Client :: new ( ) )
31
+ . with_init ( Extension ( OtelName ( "mcp-graphql-client" . into ( ) ) ) )
32
+ . with ( TracingMiddleware :: default ( ) )
33
+ . build ( )
34
+ } ) ;
35
+
27
36
/// Able to be executed as a GraphQL operation
28
37
pub trait Executable {
29
38
/// Get the persisted query ID to be executed, if any
@@ -86,12 +95,7 @@ pub trait Executable {
86
95
}
87
96
}
88
97
89
- let client = ClientBuilder :: new ( reqwest:: Client :: new ( ) )
90
- . with_init ( Extension ( OtelName ( "mcp-graphql-client" . into ( ) ) ) )
91
- . with ( TracingMiddleware :: default ( ) )
92
- . build ( ) ;
93
-
94
- let result = client
98
+ let result = GRAPHQL_CLIENT
95
99
. post ( request. endpoint . as_str ( ) )
96
100
. headers ( self . headers ( & request. headers ) )
97
101
. body ( Value :: Object ( request_body) . to_string ( ) )
0 commit comments