Skip to content

Repository files navigation

GQLXY

An unopinionated C++20 GraphQL server engine.

Why

I needed a GraphQL server in C++ for a legacy codebase. The options were quickly exhausted: cppgraphqlgen is complex and didn't fit my needs, libgraphqlparser is just a parser. Nothing resembled what Apollo does for the JavaScript ecosystem — a simple, ergonomic way to wire up a schema.

I wanted to write this:

Schema schema({
    .typeDefs = R"(
        type Query {
            hello: String
            user: User
        }
        type User {
            id: ID!
            name: String!
            email: String!
        }
    )",
    .resolvers = {
        {"Query", Resolver{
            {"hello", "Hello, world!"},
            {"user", Resolver{
                {"id", "1"},
                {"name", "John Doe"},
                {"email", "john@example.com"}
            }}
        }}
    }
});

auto result = schema.Resolve({.query = "{ hello user { name } }"}).get();

So, like a normal C++ dev, I wrote it myself.

What it is

GQLXY is a minimalist, unopinionated GraphQL execution engine for C++20. It handles SDL parsing, query execution, introspection, subscriptions, schema stitching, and Apollo Federation — without dictating how your application is structured.

It doesn't care how your server works underneath. Want sync lambdas? std::future? C++20 coroutines? Callbacks? Use whatever fits your codebase.

Features

  • SDL schema parsing — objects, interfaces, unions, enums, scalars, input types
  • Query execution with field arguments, variables, aliases, fragments
  • All four resolver styles: sync functions, std::future, coroutines, callbacks
  • Full introspection (__schema, __type, __typename)
  • Per-field error handling — one failing resolver doesn't abort the request
  • @skip / @include and custom directives
  • Custom scalars with input coercion and output serialization
  • Abstract type resolution for interfaces and unions
  • Serial mutation execution (spec §6.3.1)
  • Query validation — undeclared variables, unknown fields, missing required arguments
  • Real-time subscriptions via PubSub
  • Schema stitching — merge multiple schemas into one
  • Apollo Federation subgraph support (@key, _service, _entities)
  • Opt-in standalone HTTP/WebSocket/SSE server
  • MCP (Model Context Protocol) server — expose your GraphQL schema as MCP tools automatically

Getting started

Add GQLXY to your vcpkg.json:

{ "dependencies": ["gqlxy-server"] }
find_package(gqlxy-server CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE gqlxy::server)

See docs/getting-started.md for FetchContent and from-source options.

MCP support

gqlxy-server can expose your GraphQL schema as an MCP (Model Context Protocol) server, making every query and mutation available as an MCP tool — with no extra wiring.

Enable it via StandaloneServerOptions:

#include <gqlxy/server/standalone/standalone_server.h>

gqlxy::server::StandaloneServer server({
    .schema = schema,
    .mcp = gqlxy::server::McpServerOptions{
        .path   = "/mcp",
        .policy = gqlxy::DefaultMcpPolicy::Enabled
    }
});
server.Start();
  • DefaultMcpPolicy::Enabled — all fields exposed by default; opt out per-field with @mcp(include: false).
  • DefaultMcpPolicy::Hidden — no fields exposed by default; opt in per-field with @mcp(include: true).
  • DefaultMcpPolicy::Disabled — MCP endpoint disabled entirely.

You can also use CreateMcpRegistry independently of the standalone server to integrate MCP into your own HTTP layer.

Documentation

Check out the full documentation on https://gqlxy.dev

License

MIT

About

An unopinionated C++ GraphQL Server

Resources

Code of conduct

Contributing

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages