@toolprint/mcp-graphql-forge
Version:
MCP server that exposes GraphQL APIs to AI tools through automatic schema introspection and tool generation
97 lines • 3.48 kB
JavaScript
import { GraphQLClient } from 'graphql-request';
import { getIntrospectionQuery, buildClientSchema } from 'graphql';
import { writeFileSync } from 'fs';
import { join } from 'path';
import logger from './logger.js';
export async function introspectGraphQLSchema(config) {
const client = new GraphQLClient(config.endpoint, {
headers: config.headers || {}
});
try {
const introspectionQuery = getIntrospectionQuery();
const result = await client.request(introspectionQuery);
if (config.outputPath) {
writeFileSync(config.outputPath, JSON.stringify(result, null, 2));
logger.info(`Schema introspection saved to: ${config.outputPath}`);
}
return result;
}
catch (error) {
logger.error('Failed to introspect GraphQL schema:', error);
throw error;
}
}
export function generateToolsFromSchema(introspectionResult) {
const schema = buildClientSchema(introspectionResult);
const tools = [];
const queryType = schema.getQueryType();
const mutationType = schema.getMutationType();
if (queryType) {
const fields = queryType.getFields();
for (const [fieldName, field] of Object.entries(fields)) {
tools.push({
name: `query_${fieldName}`,
description: field.description || `Execute GraphQL query: ${fieldName}`,
inputSchema: {
type: "object",
properties: {
variables: {
type: "object",
description: "Variables for the GraphQL query"
}
}
}
});
}
}
if (mutationType) {
const fields = mutationType.getFields();
for (const [fieldName, field] of Object.entries(fields)) {
tools.push({
name: `mutation_${fieldName}`,
description: field.description || `Execute GraphQL mutation: ${fieldName}`,
inputSchema: {
type: "object",
properties: {
variables: {
type: "object",
description: "Variables for the GraphQL mutation"
}
}
}
});
}
}
return tools;
}
async function main() {
const endpoint = process.env.GRAPHQL_ENDPOINT;
if (!endpoint) {
logger.error('Please set GRAPHQL_ENDPOINT environment variable');
process.exit(1);
}
const headers = {};
if (process.env.GRAPHQL_AUTH_HEADER) {
headers.Authorization = process.env.GRAPHQL_AUTH_HEADER;
}
const outputPath = join(process.cwd(), 'schema.json');
const toolsPath = join(process.cwd(), 'tools.json');
try {
const introspectionResult = await introspectGraphQLSchema({
endpoint,
headers,
outputPath
});
const tools = generateToolsFromSchema(introspectionResult);
writeFileSync(toolsPath, JSON.stringify(tools, null, 2));
logger.info(`Generated ${tools.length} tools and saved to: ${toolsPath}`);
}
catch (error) {
logger.error('Introspection failed:', error);
process.exit(1);
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
main();
}
//# sourceMappingURL=introspect.js.map