MCP Server

MCP Server GraphQL Endpoints

Applies to
Gatewayruntime for API, AI, and MCP gateways
Hosting
Managed EdgeManaged DedicatedSelf-Hosted

The MCP Server Handler supports GraphQL endpoints through the x-zuplo-route OpenAPI extension. This allows you to expose GraphQL APIs as MCP tools with automatic schema introspection and query execution capabilities.

When you configure a route with the GraphQL extension, the MCP server automatically generates two tools:

  1. Introspection tool - Fetches the GraphQL schema so AI systems can understand available queries, mutations, and types
  2. Execute tool - Executes GraphQL queries against the endpoint

This enables AI systems to dynamically discover and interact with GraphQL APIs without requiring manual tool definitions for each query.

Quick Start

1. Configure a GraphQL Endpoint

Add a route that forwards to your GraphQL endpoint and include the x-zuplo-route.mcp configuration:

JSONCode
{ "openapi": "3.1.0", "info": { "version": "1.0.0" }, "paths": { "/graphql": { "post": { "operationId": "graphql", "summary": "GraphQL API endpoint", "x-zuplo-route": { "handler": { "export": "urlForwardHandler", "module": "$import(@zuplo/runtime)", "options": { "baseUrl": "https://api.example.com", "followRedirects": true } }, "mcp": { "type": "graphql" } } } } } }

2. Add to Your MCP Server

Include the GraphQL route in your MCP Server configuration using the operations array:

JSONCode
{ "paths": { "/mcp": { "post": { "summary": "MCP server", "operationId": "mcp-server", "x-zuplo-route": { "corsPolicy": "none", "handler": { "export": "mcpServerHandler", "module": "$import(@zuplo/runtime)", "options": { "name": "My MCP Server", "version": "1.0.0", "operations": [ { "file": "./config/routes.oas.json", "id": "graphql" } ] } } } } } } }

This configuration automatically creates:

  • graphql_introspect - Tool to fetch the GraphQL schema
  • graphql_execute - Tool to execute GraphQL queries

Configuration Options

The x-zuplo-route.mcp configuration for GraphQL supports the following options:

  • type: Must be set to "graphql"
  • enabled: Whether the GraphQL MCP capabilities are enabled (default: true).
  • introspectionTool: Configuration for the introspection tool.
    • name: Custom name for the introspection tool.
    • description: Custom description for the introspection tool.
  • executeTool: Configuration for the execute tool.
    • name: Custom name for the execute tool.
    • description: Custom description for the execute tool.

For example:

JSONCode
{ "paths": { "/graphql": { "post": { "operationId": "github_graphql", "x-zuplo-route": { "handler": { "export": "urlForwardHandler", "module": "$import(@zuplo/runtime)", "options": { "baseUrl": "https://api.github.com" } }, "mcp": { "type": "graphql", "introspectionTool": { "name": "github_schema", "description": "Fetch the GitHub GraphQL schema" }, "executeTool": { "name": "github_query", "description": "Execute a query against the GitHub GraphQL API" } } } } } } }

Custom GraphQL Tools

For more complex scenarios like bounded mutations or queries with complex logic, you can create custom GraphQL tools as endpoints using the Zuplo custom MCP tool patterns and the graphql library.

Here's a simple example of a custom bounded GraphQL query that expects an id input from the MCP client:

JSONCode
{ "paths": { "/graphql/ship": { "post": { "summary": "Get details about a specific ship", "operationId": "get_ship", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["id"], "properties": { "id": { "type": "string", "description": "The ID of the ship to query" } } } } } }, "x-zuplo-route": { "handler": { "export": "default", "module": "$import(./modules/get-ship)" } } } } } }

In your handler (modules/get-ship.ts):

TypeScriptCode
import { ZuploContext, ZuploRequest } from "@zuplo/runtime"; export default async function handler( request: ZuploRequest, context: ZuploContext, ) { const { id } = await request.json(); const query = ` query GetShip($id: ID!) { ship(id: $id) { name model manufacturer } } `; const response = await fetch("https://api.example.com/graphql", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ query, variables: { id }, }), }); return response; }

For more complex custom tools with validation, error handling, and multi-step workflows, see the Custom Tools documentation.

See Also

Last modified on