A Model Context Protocol (MCP) server that dynamically generates tools for any GraphQL API by introspecting its schema.
- Automatic tool generation from GraphQL schema introspection
- Support for all GraphQL queries and mutations
- Type-safe variable handling
- Automatic query generation with smart field selection
- Error handling and validation
- Function exposure control via exposed.yaml
- Bearer token authentication support
The server automatically manages which GraphQL functions are exposed as MCP tools through an exposed.yaml file:
- First run: Server discovers all GraphQL queries and mutations, creates
exposed.yamlwith all functions set totrue - Subsequent runs: Only functions marked as
trueinexposed.yamlare registered as MCP tools - Dynamic updates: New functions are automatically added to the file with default
truevalue - Cleanup: Functions that no longer exist in the schema are removed from the file
exposed:
queries:
getUser: true
listPosts: false
searchContent: true
mutations:
createUser: true
deleteUser: false
updatePost: true- Set a function to
falseto disable it (won't be registered as MCP tool) - Set a function to
trueto enable it (will be registered as MCP tool) - The file is automatically updated when the schema changes
npm installSet the GraphQL endpoint URL via environment variable or command line argument:
# Via environment variable
export GRAPHQL_URL="https://api.example.com/graphql"
# Via command line argument
node src/index.js --graphql-url "https://api.example.com/graphql"For GraphQL APIs requiring Bearer token authentication:
# Via environment variable
export GRAPHQL_TOKEN="your-bearer-token"
# Via command line argument
node src/index.js --token "your-bearer-token"
# Both URL and token as arguments
node src/index.js --graphql-url "https://api.example.com/graphql" --token "your-bearer-token"npm start
# or
node src/index.jsnpm run start:http
# or
node src/index.js --transport http
# Custom port
node src/index.js --transport http --port 8080# STDIO transport
npm run dev
# HTTP transport
npm run dev:httpnode src/index.js [options]
Options:
-t, --transport <type> Transport type: stdio or http (default: stdio)
-p, --port <number> HTTP port (default: 3000)
-u, --graphql-url <url> GraphQL endpoint URL
-T, --token <token> Bearer token for authentication
-q, --query-prefix <str> Prefix for query tools (default: none)
-m, --mutation-prefix <str> Prefix for mutation tools (default: none)
-h, --help Show help messageAdd to your Claude Desktop configuration:
{
"mcpServers": {
"graphql": {
"command": "node",
"args": ["/path/to/graphql-mcp-server/src/index.js"],
"env": {
"GRAPHQL_URL": "https://api.example.com/graphql",
"GRAPHQL_TOKEN": "your-bearer-token"
}
}
}
}Alternative using command line arguments:
{
"mcpServers": {
"graphql": {
"command": "node",
"args": [
"/path/to/graphql-mcp-server/src/index.js",
"--graphql-url", "https://api.example.com/graphql",
"--token", "your-bearer-token"
]
}
}
}For HTTP transport, start the server separately:
# Start the server with environment variables
GRAPHQL_URL="https://api.example.com/graphql" GRAPHQL_TOKEN="your-bearer-token" node src/index.js --transport http --port 3000
# Or using command line arguments
node src/index.js --transport http --port 3000 --graphql-url "https://api.example.com/graphql" --token "your-bearer-token"Then configure your MCP client to connect to the HTTP endpoint at http://localhost:3000/mcp.
When using HTTP transport, you can secure the MCP server with bearer token authentication:
# Set AUTH_TOKEN environment variable
export AUTH_TOKEN="your-mcp-secret-token"
node src/index.js --transport http
# Or in docker-compose.yml
environment:
- AUTH_TOKEN=your-mcp-secret-tokenWhen AUTH_TOKEN is set:
- All HTTP requests to the MCP server must include:
Authorization: Bearer your-mcp-secret-token - Requests without valid tokens receive 401 Unauthorized
- If
AUTH_TOKENis not set, the server allows open access (no authentication required)
When running with HTTP transport:
- POST /mcp - Main MCP protocol endpoint
- GET /mcp - Returns method not allowed (405)
# Without authentication (when AUTH_TOKEN is not set)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
# With authentication (when AUTH_TOKEN is set)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-mcp-secret-token" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
# Call a GraphQL query tool
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "query_getUser",
"arguments": {
"variables": {
"id": "123"
}
}
}
}'- On startup, the server connects to the specified GraphQL endpoint (with optional Bearer token authentication)
- It loads the
exposed.yamlconfiguration file (creates it if it doesn't exist) - It performs an introspection query to fetch the complete schema
- For each query and mutation in the schema, it checks if the function is enabled in
exposed.yaml - Only enabled functions are registered as MCP tools with prefixes:
query_for queries andmutation_for mutations - New functions discovered in the schema are automatically added to
exposed.yamlas enabled - When a tool is called, it constructs the appropriate GraphQL query/mutation and executes it
- Results are returned as formatted JSON
- Queries:
query_<fieldName>(e.g.,query_getUser,query_listPosts) - Mutations:
mutation_<fieldName>(e.g.,mutation_createUser,mutation_updatePost)
| Variable | Description | Required |
|---|---|---|
GRAPHQL_URL |
GraphQL endpoint URL | Yes (if not provided via --graphql-url) |
GRAPHQL_TOKEN |
Bearer token for GraphQL API authentication | No |
AUTH_TOKEN |
Bearer token for MCP server authentication (HTTP transport only) | No |
| File | Description |
|---|---|
exposed.yaml |
Configuration file controlling which GraphQL functions are exposed as MCP tools |
The server supports two transport protocols:
- Default transport for MCP
- Uses standard input/output for communication
- Suitable for direct integration with MCP clients
- Lower overhead, faster communication
- StreamableHTTP transport using MCP SDK
- JSON-RPC over HTTP
- Express.js server for HTTP handling
- Suitable for web applications and remote access
- Standard MCP protocol compliance
For a GraphQL schema with:
type Query {
getUser(id: ID!): User
listPosts(limit: Int): [Post]
}
type Mutation {
createUser(input: CreateUserInput!): User
}The MCP server will generate tools:
query_getUser- with requiredidparameterquery_listPosts- with optionallimitparametermutation_createUser- with requiredinputparameter
MIT