Galley MCP Server
A Model Context Protocol (MCP) server for Galley GraphQL API integration using Apollo MCP Server with mandatory automatic schema introspection. The server introspects your Galley GraphQL schema on startup and provides seamless integration with MCP clients like Claude, Cursor, and VS Code.
🚀 Quick Start
Prerequisites
- Docker installed on your system
- Galley API authentication (X-API-KEY or Bearer token)
- Network access to Galley GraphQL endpoints
Build and Run
# Option 1: Use pre-built image from public ECR (recommended)
docker run -i -e X_API_KEY="your_api_key_here" public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Option 2: Build from source
# Clone the repository
git clone <your-repo-url>
cd galley-mcp
# Build the Docker image
docker build -t galley-mcp .
# Run with X-API-KEY authentication
docker run -i -e X_API_KEY="your_api_key_here" galley-mcp
# Or run with x-user-api-key authentication
docker run -i -e X_USER_API_KEY="your_user_api_key_here" galley-mcp
# Or run with Bearer token authentication
docker run -i -e GALLEY_AUTH_TOKEN="your_bearer_token_here" galley-mcp
Pre-built Images
Pre-built multi-architecture Docker images are available from Amazon ECR Public Gallery:
- Registry:
public.ecr.aws/o0r1r5q2/galley-mcp
- Latest:
public.ecr.aws/o0r1r5q2/galley-mcp:latest
- Architectures:
linux/amd64
,linux/arm64
- Automatic releases: Images are automatically built and published on every commit to master branch
Version Tags Available:
latest
- Latest stable version from master branchv1.0.0
,v1.1.0
, etc. - Semantic version tags from releases1.0.0
,1.1.0
, etc. - Version tags without 'v' prefixdevelop
- Latest development version from develop branch
What Happens on Startup
- Schema Introspection: Automatically introspects the Galley GraphQL schema from
https://app.galleysolutions.com/graphql
- Schema Validation: Verifies the schema was successfully retrieved (startup fails if introspection fails)
- MCP Server Start: Launches Apollo MCP Server with the introspected schema and your operations
Important: Interactive Mode Required
MCP servers need to run in interactive mode (-i
flag) to communicate with MCP clients. This allows:
- Bidirectional communication between the client and server
- Real-time request/response handling for GraphQL operations
- Proper stdin/stdout stream management for MCP protocol
Always use docker run -i
when running the container for MCP client integration.
📋 Docker Installation
Linux (Ubuntu/Debian)
# Update package index
sudo apt-get update
# Install required packages
sudo apt-get install ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Add Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Add your user to docker group (optional, to run without sudo)
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
macOS
Option 1: Docker Desktop (Recommended)
- Download Docker Desktop from https://www.docker.com/products/docker-desktop
- Install the
.dmg
file - Launch Docker Desktop from Applications
- Verify installation:
docker --version
Option 2: Homebrew
# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Docker
brew install --cask docker
# Launch Docker Desktop
open /Applications/Docker.app
# Verify installation
docker --version
Windows
Option 1: Docker Desktop (Recommended)
- Download Docker Desktop from https://www.docker.com/products/docker-desktop
- Run the installer
- Restart your computer when prompted
- Launch Docker Desktop
- Verify installation:
docker --version
Option 2: WSL2 + Docker (Advanced)
# Enable WSL2
wsl --install
# Install Docker in WSL2
# Follow Linux installation steps inside WSL2
⚙️ Configuration
Environment Variables
Variable | Description | Default | Required |
---|---|---|---|
X_API_KEY | Galley X-API-KEY authentication | - | * |
X_USER_API_KEY | Galley x-user-api-key authentication | - | * |
GALLEY_AUTH_TOKEN | Galley Bearer token authentication | - | * |
STAGING | Use staging environment endpoints | false | No |
ENDPOINT | GraphQL endpoint URL for MCP operations | https://app.galleysolutions.com/graphql (prod) or https://staging-app.galleysolutions.com/graphql (staging) | No |
INTROSPECT_ENDPOINT | Schema introspection endpoint | Same as ENDPOINT | No |
USER_DIRECTORY | Additional operations directory to mount | - | No |
APOLLOGRAPHQL_CLIENT_NAME | Client identification header | galley-mcp-server@{hostname} | No |
SCHEMA_OUTPUT | Schema output file path | /app/schema.graphql | No |
MCP_DEBUG | Enable debug mode with verbose logging | false | No |
DISABLE_INTROSPECTION | Disable introspection capability on MCP server | false | No |
ALLOW_MUTATIONS | Control mutation permissions: none , explicit , or all | none | No |
Authentication Priority: X_API_KEY
takes precedence over X_USER_API_KEY
, which takes precedence over GALLEY_AUTH_TOKEN
if multiple are provided.
Environment Modes
The server supports both production and staging environments:
Production Mode (Default)
# Uses production endpoints by default
docker run -i -e X_API_KEY="your_key" public.ecr.aws/o0r1r5q2/galley-mcp:latest
- Endpoint:
https://app.galleysolutions.com/graphql
- Introspection:
https://app.galleysolutions.com/graphql
Staging Mode
# Enable staging mode
docker run -i -e X_API_KEY="your_key" -e STAGING=true public.ecr.aws/o0r1r5q2/galley-mcp:latest
- Endpoint:
https://staging-app.galleysolutions.com/graphql
- Introspection:
https://staging-app.galleysolutions.com/graphql
Custom Endpoints
# Override specific endpoints (takes precedence over STAGING flag)
docker run -i \
-e X_API_KEY="your_key" \
-e ENDPOINT="https://custom.galleysolutions.com/graphql" \
-e INTROSPECT_ENDPOINT="https://custom-introspect.galleysolutions.com/graphql" \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
Debug Mode
Set MCP_DEBUG=true
to enable verbose logging and detailed output:
- Schema Introspection: Shows detailed Rover output and schema statistics
- Apollo MCP Server: Enables debug logging with
--log DEBUG
- Configuration: Displays all environment variables and settings
- Silent Mode: When
MCP_DEBUG=false
(default), minimal output for production use
# Enable debug mode
docker run -i -e X_API_KEY="your_key" -e MCP_DEBUG=true public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Silent mode (default)
docker run -i -e X_API_KEY="your_key" public.ecr.aws/o0r1r5q2/galley-mcp:latest
Schema Introspection
- Mandatory: Schema introspection runs on every startup and cannot be skipped
- Fail-Fast: Server will not start if schema introspection fails
- Authentication: Uses the same authentication method (X-API-KEY or Bearer token) for introspection
- Output: Schema is saved to
/app/schema.graphql
and used by Apollo MCP Server
Introspection Control
The MCP server supports introspection capabilities that allow clients to explore the GraphQL schema dynamically. You can control this behavior with the DISABLE_INTROSPECTION
environment variable:
- Default behavior: Introspection is enabled (
DISABLE_INTROSPECTION=false
) - Security consideration: Disable introspection in production environments for security
- Client impact: When disabled, MCP clients cannot dynamically explore the schema
# Enable introspection (default)
docker run -i -e X_API_KEY="your_key" public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Disable introspection for production
docker run -i -e X_API_KEY="your_key" -e DISABLE_INTROSPECTION=true public.ecr.aws/o0r1r5q2/galley-mcp:latest
Mutation Control
The MCP server provides fine-grained control over GraphQL mutations through the ALLOW_MUTATIONS
environment variable. This helps maintain data safety and control what operations MCP clients can perform:
none
(default): Don't allow any mutations - read-only accessexplicit
: Allow only pre-defined mutations from operation files, but don't allow the LLM to build new mutations dynamicallyall
: Allow the LLM to build and execute mutations dynamically (highest risk)
# Read-only mode (default)
docker run -i -e X_API_KEY="your_key" public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Allow only explicit mutations from operation files
docker run -i -e X_API_KEY="your_key" -e ALLOW_MUTATIONS=explicit public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Allow LLM to build mutations (use with caution)
docker run -i -e X_API_KEY="your_key" -e ALLOW_MUTATIONS=all public.ecr.aws/o0r1r5q2/galley-mcp:latest
Security Recommendation: Use none
or explicit
in production environments to prevent unintended data modifications.
Example Configurations
Production Setup (Read-only)
docker run -i \
-e X_API_KEY="prod_api_key_here" \
-e ENDPOINT="https://app.galleysolutions.com/graphql" \
-e INTROSPECT_ENDPOINT="https://app.galleysolutions.com/graphql" \
-e APOLLOGRAPHQL_CLIENT_NAME="production-server@prod-host" \
-e DISABLE_INTROSPECTION=true \
-e ALLOW_MUTATIONS=none \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
Production Setup (Explicit Mutations Only)
docker run -i \
-e X_API_KEY="prod_api_key_here" \
-e ENDPOINT="https://app.galleysolutions.com/graphql" \
-e INTROSPECT_ENDPOINT="https://app.galleysolutions.com/graphql" \
-e APOLLOGRAPHQL_CLIENT_NAME="production-server@prod-host" \
-e DISABLE_INTROSPECTION=true \
-e ALLOW_MUTATIONS=explicit \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
Development with Custom Operations and Debug
docker run -i \
-e X_API_KEY="dev_api_key_here" \
-e USER_DIRECTORY="/custom/operations" \
-e MCP_DEBUG=true \
-e ALLOW_MUTATIONS=all \
-v ./custom-operations:/custom/operations \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
Staging Environment
docker run -i \
-e X_API_KEY="staging_api_key_here" \
-e STAGING=true \
-e APOLLOGRAPHQL_CLIENT_NAME="staging-server@staging-host" \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
🔌 MCP Client Integration
Claude Desktop
Install Claude Desktop from https://claude.ai/download
Configure MCP Server in Claude's settings:
Read-only configuration (recommended):
{ "mcpServers": { "galley": { "command": "docker", "args": [ "run", "--rm", "-i", "-e", "X_API_KEY=your_api_key_here", "-e", "DISABLE_INTROSPECTION=true", "-e", "ALLOW_MUTATIONS=none", "public.ecr.aws/o0r1r5q2/galley-mcp:latest" ], "env": {} } } }
Allow explicit mutations:
{ "mcpServers": { "galley": { "command": "docker", "args": [ "run", "--rm", "-i", "-e", "X_API_KEY=your_api_key_here", "-e", "ALLOW_MUTATIONS=explicit", "public.ecr.aws/o0r1r5q2/galley-mcp:latest" ], "env": {} } } }
Restart Claude Desktop to load the MCP server
Cursor IDE
Install Cursor from https://cursor.sh
Add MCP Configuration in Cursor settings:
- Open Settings → Extensions → MCP
- Add new server configuration:
{ "name": "galley", "command": "docker", "args": [ "run", "--rm", "-i", "-e", "X_API_KEY=your_api_key_here", "public.ecr.aws/o0r1r5q2/galley-mcp:latest" ] }
Enable the MCP server in Cursor's MCP panel
VS Code
Install VS Code from https://code.visualstudio.com
Install MCP Extension:
- Open Extensions panel (
Ctrl+Shift+X
) - Search for "Model Context Protocol"
- Install the MCP extension
- Open Extensions panel (
Configure MCP Server:
- Open VS Code settings (
Ctrl+,
) - Search for "MCP"
- Add server configuration:
{ "mcp.servers": { "galley": { "command": "docker", "args": [ "run", "--rm", "-i", "-e", "X_API_KEY=your_api_key_here", "public.ecr.aws/o0r1r5q2/galley-mcp:latest" ] } } }
- Open VS Code settings (
🛠️ Development
Custom Operations
Add your own GraphQL operations by mounting a custom directory:
# Create custom operations directory
mkdir -p ./my-operations
# Add your .graphql files
echo 'query MyCustomQuery { viewer { id } }' > ./my-operations/MyQuery.graphql
# Run with custom operations
docker run -i \
-e X_API_KEY="your_api_key" \
-e USER_DIRECTORY="/custom" \
-v ./my-operations:/custom \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
Schema Introspection
The server automatically introspects the Galley GraphQL schema on startup. The schema is saved to /app/schema.graphql
and used by the Apollo MCP Server.
Key Features:
- Mandatory execution: Cannot be skipped or disabled
- Fail-fast behavior: Server stops if introspection fails
- Authentication: Uses same credentials as MCP operations
- Real-time schema: Always gets the latest schema on startup
- Client identification: Sends
apollographql-client-name
header for tracking
Built-in Tools
The Docker image includes:
- Apollo MCP Server: Latest version installed to
/usr/local/bin
- Rover: Apollo's GraphQL CLI tool for schema introspection
- Debian Bookworm Slim: Lightweight base image with glibc support
Debugging
Enable debug mode for detailed output and troubleshooting:
# Enable debug mode for verbose logging
docker run -i -e X_API_KEY="your_api_key" -e MCP_DEBUG=true public.ecr.aws/o0r1r5q2/galley-mcp:latest
# View container logs
docker logs <container_id>
# Run interactively to see all output
docker run -it -e X_API_KEY="your_api_key" -e MCP_DEBUG=true public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Test with different endpoints in debug mode
docker run -i \
-e X_API_KEY="your_api_key" \
-e MCP_DEBUG=true \
-e INTROSPECT_ENDPOINT="https://staging-app.galleysolutions.com/graphql" \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
Debug Mode Features:
- Shows all configuration values
- Displays Rover introspection command and output
- Shows schema statistics (lines, file size)
- Enables Apollo MCP Server debug logging
- Displays authentication method being used
📁 Project Structure
galley-mcp/
├── Dockerfile # Docker container with Apollo MCP Server + Rover
├── entrypoint.sh # Main startup script with mandatory introspection
├── introspect-schema.sh # Schema introspection script using Rover
├── operations/ # GraphQL operations directory
│ └── GetRecipesByName.graphql # Example Galley recipe query
└── README.md # This comprehensive guide
Key Components
- entrypoint.sh: Orchestrates schema introspection and server startup
- introspect-schema.sh: Uses Rover to fetch the latest Galley GraphQL schema
- operations/: Contains your GraphQL operations (queries, mutations, subscriptions)
- Dockerfile: Multi-stage build with Apollo MCP Server and Rover pre-installed
🔄 CI/CD Pipeline
The project includes automated CI/CD using GitHub Actions with two specialized workflows:
🚀 Release Workflow (release.yml
)
Triggers: Push to master
branch
What it does:
- Auto-versioning: Automatically increments patch version from latest tag
- GitHub Releases: Creates release with auto-generated notes
- Multi-architecture builds: Builds for
linux/amd64
andlinux/arm64
- Multiple Docker tags: Publishes
latest
,v1.0.1
, and1.0.1
tags - Release documentation: Includes Docker image URLs and commit info
Example: Push to master → Creates v1.0.1
release + publishes Docker images
🔧 Build Workflow (build-and-push.yml
)
Triggers:
- Push to
develop
branch - Pull requests to
master
What it does:
- Development builds: Publishes
develop
tag for development branch - PR validation: Builds (but doesn't publish) for pull requests
- Multi-architecture: Supports both
linux/amd64
andlinux/arm64
- Caching: Uses GitHub Actions cache for faster builds
Available Docker Tags
latest
- Latest stable release from master branchv1.0.1
,1.0.1
- Semantic version tags from releasesdevelop
- Latest development version from develop branch
Repository Setup
To set up the CI/CD pipeline, configure these GitHub repository secrets:
AWS_ACCESS_KEY_ID
: AWS access key for ECR push permissionsAWS_SECRET_ACCESS_KEY
: AWS secret key for ECR push permissions
Permissions: The release workflow needs contents: write
permission (automatically configured).
The ECR repository needs to be created as a public repository in us-east-1
region with the name galley-mcp
.
🔧 Troubleshooting
Common Issues
Authentication Errors
# Verify your API key is correct
docker run -i -e X_API_KEY="your_key" public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Check if endpoint is accessible
curl -H "X-API-KEY: your_key" https://app.galleysolutions.com/graphql
Schema Introspection Fails
# Check network connectivity to introspection endpoint
docker run --rm -e X_API_KEY="your_key" public.ecr.aws/o0r1r5q2/galley-mcp:latest ping -c 3 app.galleysolutions.com
# Test GraphQL endpoint manually
curl -X POST -H "Content-Type: application/json" \
-H "X-API-KEY: your_key" \
-d '{"query": "{ __schema { types { name } } }"}' \
https://app.galleysolutions.com/graphql
# Check if introspection endpoint is different from operation endpoint
docker run -i \
-e X_API_KEY="your_key" \
-e INTROSPECT_ENDPOINT="https://staging-app.galleysolutions.com/graphql" \
public.ecr.aws/o0r1r5q2/galley-mcp:latest
# Verify authentication method
# Try with Bearer token instead of X-API-KEY
docker run -i -e GALLEY_AUTH_TOKEN="your_token" public.ecr.aws/o0r1r5q2/galley-mcp:latest
Apollo MCP Server Issues
# Verify Apollo MCP Server is installed correctly
docker run --rm public.ecr.aws/o0r1r5q2/galley-mcp:latest which apollo-mcp-server
docker run --rm public.ecr.aws/o0r1r5q2/galley-mcp:latest apollo-mcp-server --version
# Check if schema file exists after introspection
docker run --rm -e X_API_KEY="your_key" public.ecr.aws/o0r1r5q2/galley-mcp:latest ls -la /app/schema.graphql
Docker Issues
# Check Docker is running
docker --version
# Pull latest base image
docker pull debian:bookworm-slim
# Rebuild without cache
docker build --no-cache -t galley-mcp .
Getting Help
- Check startup logs:
docker logs <container_id>
- Shows introspection and startup process - Verify authentication: Ensure your X-API-KEY or Bearer token is valid
- Test endpoints: Confirm both introspection and operation endpoints are accessible
- Check Docker: Make sure you're using the latest Docker version
- Rebuild image: Try
docker build --no-cache -t galley-mcp .
to force fresh build
Common Success Indicators
When everything works correctly, you should see:
Silent Mode (MCP_DEBUG=false, default):
Error: Schema introspection failed. Server cannot start without valid schema.
(Only errors are shown)
Debug Mode (MCP_DEBUG=true):
Starting Apollo MCP Server with Galley configuration...
Endpoint: https://staging-app.galleysolutions.com/graphql
Operations directory: /app/operations
Graph reference: Galley-dtd1yd@current
Client name: galley-mcp-server@hostname
Debug mode: true
Running mandatory schema introspection...
Rover is available
Introspecting schema from: https://app.galleysolutions.com/graphql
Using X-API-KEY for introspection
Running: rover graph introspect https://app.galleysolutions.com/graphql --output /app/schema.graphql --log DEBUG --header X-API-KEY:your_key --header apollographql-client-name:galley-mcp-introspect@hostname
Schema introspection completed successfully!
Schema saved to: /app/schema.graphql
Schema file: XXXX lines, XXXkB
Schema introspection completed successfully, starting server...
Using X-API-KEY authentication
📄 License
[Your License Here]
🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
For more information about the Model Context Protocol, visit https://modelcontextprotocol.io