33import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ;
44import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" ;
55import { parse } from "graphql/language" ;
6- import {
7- buildClientSchema ,
8- getIntrospectionQuery ,
9- printSchema ,
10- } from "graphql/utilities" ;
116import yargs from "yargs" ;
127import { hideBin } from "yargs/helpers" ;
138import { z } from "zod" ;
9+ import {
10+ introspectEndpoint ,
11+ introspectLocalSchema ,
12+ } from "./helpers/introspection.js" ;
1413import { getVersion } from "./helpers/package.js" with { type : "macro" } ;
1514
1615const graphQLSchema = z . object ( {
@@ -23,6 +22,7 @@ const ConfigSchema = z.object({
2322 allowMutations : z . boolean ( ) . default ( false ) ,
2423 endpoint : z . string ( ) . url ( ) . default ( "http://localhost:4000/graphql" ) ,
2524 headers : z . record ( z . string ( ) ) . default ( { } ) ,
25+ schema : z . string ( ) . optional ( ) ,
2626} ) ;
2727
2828type Config = z . infer < typeof ConfigSchema > ;
@@ -49,6 +49,10 @@ function parseArgs(): Config {
4949 description : "JSON string of headers to send with requests" ,
5050 default : "{}" ,
5151 } )
52+ . option ( "schema" , {
53+ type : "string" ,
54+ description : "Path to a local GraphQL schema file" ,
55+ } )
5256 . help ( )
5357 . parseSync ( ) ;
5458
@@ -85,33 +89,23 @@ server.resource(
8589 new URL ( config . endpoint ) . href ,
8690 async ( uri ) => {
8791 try {
88- const response = await fetch ( uri , {
89- method : "POST" ,
90- headers : {
91- "Content-Type" : "application/json" ,
92- } ,
93- body : JSON . stringify ( {
94- query : getIntrospectionQuery ( ) ,
95- } ) ,
96- } ) ;
97-
98- if ( ! response . ok ) {
99- throw new Error ( `GraphQL request failed: ${ response . statusText } ` ) ;
92+ let schema : string ;
93+ if ( config . schema ) {
94+ schema = await introspectLocalSchema ( config . schema ) ;
95+ } else {
96+ schema = await introspectEndpoint ( config . endpoint ) ;
10097 }
10198
102- const responseJson = await response . json ( ) ;
103- const schema = buildClientSchema ( responseJson . data ) ;
104-
10599 return {
106100 contents : [
107101 {
108102 uri : uri . href ,
109- text : printSchema ( schema ) ,
103+ text : schema ,
110104 } ,
111105 ] ,
112106 } ;
113107 } catch ( error ) {
114- throw new Error ( `Failed to fetch GraphQL schema: ${ error } ` ) ;
108+ throw new Error ( `Failed to get GraphQL schema: ${ error } ` ) ;
115109 }
116110 } ,
117111) ;
@@ -122,28 +116,18 @@ server.tool(
122116 { } ,
123117 async ( ) => {
124118 try {
125- const response = await fetch ( config . endpoint , {
126- method : "POST" ,
127- headers : {
128- "Content-Type" : "application/json" ,
129- } ,
130- body : JSON . stringify ( {
131- query : getIntrospectionQuery ( ) ,
132- } ) ,
133- } ) ;
134-
135- if ( ! response . ok ) {
136- throw new Error ( `GraphQL request failed: ${ response . statusText } ` ) ;
119+ let schema : string ;
120+ if ( config . schema ) {
121+ schema = await introspectLocalSchema ( config . schema ) ;
122+ } else {
123+ schema = await introspectEndpoint ( config . endpoint ) ;
137124 }
138125
139- const responseJson = await response . json ( ) ;
140- const schema = buildClientSchema ( responseJson . data ) ;
141-
142126 return {
143127 content : [
144128 {
145129 type : "text" ,
146- text : printSchema ( schema ) ,
130+ text : schema ,
147131 } ,
148132 ] ,
149133 } ;
0 commit comments