Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .graphqlrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# GraphQL Config for mcp-graphql
# This file configures GraphQL operations and schema for the MCP server

# Schema location - can be:
# - Local file: ./schema.graphql
# - URL: https://api.example.com/graphql
# - Introspection endpoint: http://localhost:4000/graphql
schema: ${SCHEMA:-http://localhost:4000/graphql}

# Documents - GraphQL operations to load as MCP tools
# Supports glob patterns
# Update these paths to match your project structure
documents:
- './operations/**/*.graphql'
- './operations/**/*.gql'

# Extensions for additional configuration
extensions:
# Endpoint configuration
endpoints:
default:
# GraphQL endpoint URL
url: ${ENDPOINT:-http://localhost:4000/graphql}
# Headers for requests (supports environment variables)
headers:
Authorization: Bearer ${API_TOKEN}
Content-Type: application/json

# Multi-project example (commented out)
# Uncomment to use multiple projects with different configurations
# projects:
# # Production API
# production:
# schema: https://api.example.com/graphql
# documents: './operations/production/**/*.graphql'
# extensions:
# endpoints:
# default:
# url: https://api.example.com/graphql
# headers:
# Authorization: Bearer ${PROD_TOKEN}
#
# # Development API
# development:
# schema: http://localhost:4000/graphql
# documents: './operations/dev/**/*.graphql'
# extensions:
# endpoints:
# default:
# url: http://localhost:4000/graphql
# headers:
# Authorization: Bearer ${DEV_TOKEN}
41 changes: 41 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Development files
dev/
examples/
src/
test/
*.ts
!dist/**/*.d.ts

# Configuration files
.graphqlrc.yml
.graphqlrc.json
.graphqlrc
graphql.config.js
tsconfig.json
biome.json
bun.lock

# Documentation
CLAUDE.md
*.example.*

# Git and CI
.git/
.github/
.gitignore

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
93 changes: 93 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

### Development
- `bun --watch src/index.ts` - Run the MCP server in development mode with hot reload
- `bun build src/index.ts --outdir dist --target node` - Build the project for distribution
- `bun run format` - Format code using Biome (uses tabs with width 2)
- `bun run check` - Check code formatting without modifying files

### Testing GraphQL Operations
When testing GraphQL file loading functionality:
1. Create `.graphql` or `.gql` files in the `graphql/` directory
2. Run the server with `GRAPHQL_DIR=./graphql bun --watch src/index.ts`
3. Operations are automatically registered as tools with names like `gql-{operation-name}`

## Architecture

### Core Components

**MCP Server Implementation** (`src/index.ts`)
- Uses `@modelcontextprotocol/sdk` to implement a Model Context Protocol server
- Exposes GraphQL operations as MCP tools that LLMs can invoke
- Registers both static tools (`introspect-schema`, `query-graphql`) and dynamic tools from GraphQL files
- Environment-based configuration using Zod schema validation

**GraphQL File Loading System** (`src/helpers/graphql-files.ts`)
- Recursively discovers `.graphql`/`.gql` files in configured directory
- Parses GraphQL operations and extracts variable definitions
- Converts GraphQL variable types to Zod schemas for runtime validation
- Generates tool names in kebab-case format (`gql-{operation-name}`)

**Introspection Helpers** (`src/helpers/introspection.ts`)
- Supports three introspection modes:
1. Direct endpoint introspection via GraphQL introspection query
2. Local schema file parsing
3. Remote schema file fetching from URL
- Returns schema in SDL (Schema Definition Language) format

### Key Design Patterns

**Configuration Precedence**
- Environment variables ALWAYS override config files when set
- Order: Env vars > GraphQL Config > Defaults
- `ALLOW_MUTATIONS` defaults to `false` for safety
- Headers passed as JSON string in `HEADERS` env var
- Supports standard GraphQL Config formats (.graphqlrc.yml, .json, .js)

**Tool Registration Flow**
1. On startup, scan `GRAPHQL_DIR` for GraphQL files
2. Parse each file to extract operations and variables
3. Skip mutations if `ALLOW_MUTATIONS=false`
4. Register each operation as an MCP tool with appropriate Zod schema
5. Tools execute by sending the full operation content to the endpoint

**Security Model**
- Mutations disabled by default
- Same headers/endpoint used for all operations
- No dynamic query construction - only pre-defined operations from files

## Development Guidelines

### Adding New GraphQL Operations
Place `.graphql` files in the `graphql/` directory following this structure:
```
graphql/
├── queries/ # Read operations
└── mutations/ # Write operations (require ALLOW_MUTATIONS=true)
```

### Modifying Core Functionality
- Helper functions go in `src/helpers/` directory
- Use TypeScript strict mode (configured in tsconfig.json)
- Format with Biome using tabs (configured in biome.json)
- Package uses Bun as package manager ([email protected])

### Dependencies
- **Runtime**: `@modelcontextprotocol/sdk`, `graphql`, `zod`
- **Development**: Uses Bun runtime, TypeScript, Biome formatter
- **GraphQL Tools**: `@graphql-tools/schema` for schema manipulation

## Environment Variables Reference

| Variable | Required | Default | Purpose |
|----------|----------|---------|---------|
| `ENDPOINT` | No | `http://localhost:4000/graphql` | GraphQL API endpoint |
| `HEADERS` | No | `{}` | JSON string of request headers |
| `ALLOW_MUTATIONS` | No | `false` | Enable mutation operations |
| `NAME` | No | `mcp-graphql` | MCP server name |
| `SCHEMA` | No | - | Local file path or URL to schema |
| `GRAPHQL_DIR` | No | `./graphql` | Directory for .graphql files |
157 changes: 153 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,61 @@ A Model Context Protocol server that enables LLMs to interact with GraphQL APIs.

## Usage

Run `mcp-graphql` with the correct endpoint, it will automatically try to introspect your queries.
Run `mcp-graphql` with either a GraphQL Config file or environment variables. The server will automatically load your GraphQL operations as MCP tools.

### Environment Variables (Breaking change in 1.0.0)
### Configuration Methods

> **Note:** As of version 1.0.0, command line arguments have been replaced with environment variables.
The server supports two configuration methods with clear precedence:

1. **Environment Variables** (highest priority) - Always override other settings
2. **GraphQL Config File** - Standard `.graphqlrc.yml`, `.graphqlrc.json`, or `graphql.config.js`
3. **Default Values** - Built-in fallbacks

#### Precedence Order

Environment variables **always** take precedence over config files. This allows:
- Temporary overrides without changing files
- Different settings per deployment
- Easy debugging and testing
- CI/CD pipeline customization

Example:
```bash
# Override config file temporarily
ENDPOINT=http://staging.api.com/graphql npm start

# The ENDPOINT env var overrides any value in .graphqlrc.yml
```

### GraphQL Config (Recommended)

Create a `.graphqlrc.yml` file in your project root:

```yaml
schema: http://localhost:4000/graphql
documents:
- './operations/**/*.graphql'
- './queries/**/*.gql'
extensions:
endpoints:
default:
url: http://localhost:4000/graphql
headers:
Authorization: Bearer ${API_TOKEN}
```

**See [`examples/`](./examples) directory for complete configuration examples.**

Supported config formats:
- `.graphqlrc.yml` / `.graphqlrc.yaml`
- `.graphqlrc.json`
- `graphql.config.js` / `graphql.config.ts`
- `.graphqlrc` (JSON or YAML)
- `package.json` (under `graphql` key)

### Environment Variables

> **Note:** Environment variables always take precedence over GraphQL Config values when set.

| Environment Variable | Description | Default |
|----------|-------------|---------|
Expand All @@ -21,6 +71,7 @@ Run `mcp-graphql` with the correct endpoint, it will automatically try to intros
| `ALLOW_MUTATIONS` | Enable mutation operations (disabled by default) | `false` |
| `NAME` | Name of the MCP server | `mcp-graphql` |
| `SCHEMA` | Path to a local GraphQL schema file or URL (optional) | - |
| `GRAPHQL_DIR` | Directory containing .graphql/.gql files for operations | `./graphql` |

### Examples

Expand All @@ -39,6 +90,12 @@ ENDPOINT=http://localhost:3000/graphql SCHEMA=./schema.graphql npx mcp-graphql

# Using a schema file hosted at a URL
ENDPOINT=http://localhost:3000/graphql SCHEMA=https://example.com/schema.graphql npx mcp-graphql

# Using GraphQL files from a custom directory (without config file)
ENDPOINT=http://localhost:3000/graphql GRAPHQL_DIR=./my-queries npx mcp-graphql

# Using GraphQL Config file (recommended)
npx mcp-graphql # Automatically loads .graphqlrc.yml or other config formats
```

## Resources
Expand All @@ -47,13 +104,42 @@ ENDPOINT=http://localhost:3000/graphql SCHEMA=https://example.com/schema.graphql

## Available Tools

The server provides two main tools:
The server provides several tools:

1. **introspect-schema**: This tool retrieves the GraphQL schema. Use this first if you don't have access to the schema as a resource.
This uses either the local schema file, a schema file hosted at a URL, or an introspection query.

2. **query-graphql**: Execute GraphQL queries against the endpoint. By default, mutations are disabled unless `ALLOW_MUTATIONS` is set to `true`.

3. **Dynamic tools from .graphql files**: Any GraphQL operations defined in `.graphql` or `.gql` files within the `GRAPHQL_DIR` directory are automatically registered as MCP tools. Tool names follow the pattern `gql-{operation-name}` (e.g., `gql-get-user`, `gql-create-post`).

## Configuration Precedence

The server uses a clear precedence order for configuration:

```
1. Environment Variables (highest priority)
2. GraphQL Config File
3. Default Values (lowest priority)
```

This means:
- Setting `ENDPOINT=http://localhost:5000` will **always** override the config file
- Useful for temporary changes without modifying files
- Follows 12-factor app principles

### Migration Guide

To use GraphQL Config while maintaining flexibility:

1. Create a `.graphqlrc.yml` file with your base configuration
2. Use environment variables for deployment-specific overrides
3. Config file paths:
- `ENDPOINT` overrides `extensions.endpoints.default.url`
- `HEADERS` overrides `extensions.endpoints.default.headers`
- `SCHEMA` overrides `schema`
- `GRAPHQL_DIR` provides fallback if no `documents` in config

## Installation

### Installing via Smithery
Expand Down Expand Up @@ -81,10 +167,73 @@ It can be manually installed to Claude:
}
```

## GraphQL Config Support

The server now supports [GraphQL Config](https://graphql-config.com/), the standard configuration format used by GraphQL tools. This provides:

- **Standard format**: Works with existing GraphQL tooling (VSCode, GraphQL Playground, etc.)
- **Documents field**: Define operation files using glob patterns
- **Multi-project support**: Different configurations for different environments
- **Environment interpolation**: Use `${ENV_VAR}` in config values
- **Schema validation**: Validate operations against your schema

### Benefits of GraphQL Config

- Version control your GraphQL operations
- Share configuration across tools (IDEs, linters, code generators)
- Organize operations by type or domain
- Type-check operations against your schema

### Examples

The [`examples/`](./examples) directory contains:
- **Configuration examples** in YAML, JSON, and JavaScript formats
- **GraphQL operation examples** for queries and mutations
- **Multi-project setup** for managing multiple APIs

Quick start:
```bash
# Copy an example config to your project
cp examples/config/graphqlrc.yml .graphqlrc.yml

# View example operations
ls examples/graphql/
```

### Operation Files

Define your GraphQL operations in `.graphql` or `.gql` files:

```graphql
# getUser.graphql
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
```

This operation becomes available as the `gql-get-user` MCP tool.

**See [`examples/graphql/`](./examples/graphql) for more operation examples.**

### Naming Conventions

- Operations with explicit names use that name (e.g., `query GetUser` → `gql-get-user`)
- Operations without names use the filename (e.g., `userProfile.graphql` → `gql-user-profile`)
- Multi-project operations include project name (e.g., `gql-production-get-user`)
- Names are converted to kebab-case for consistency

## Security Considerations

Mutations are disabled by default as a security measure to prevent an LLM from modifying your database or service data. Consider carefully before enabling mutations in production environments.

When using GraphQL files:
- Mutation operations in `.graphql` files are skipped unless `ALLOW_MUTATIONS=true`
- Each operation is executed with the same headers and endpoint configuration

## Customize for your own server

This is a very generic implementation where it allows for complete introspection and for your users to do whatever (including mutations). If you need a more specific implementation I'd suggest to just create your own MCP and lock down tool calling for clients to only input specific query fields and/or variables. You can use this as a reference.
Loading