# Apollo MCP Server for GraphQL

Connect Claude Code (or any MCP client) to the Orchard's federated GraphQL graph via the [Apollo MCP Server](https://www.apollographql.com/docs/apollo-mcp-server).

## What it does

Exposes the federated GraphQL supergraph as MCP tools that AI models can discover and use:

| Tool | Description |
|------|-------------|
| **search** | Keyword search across 1,266+ schema types |
| **introspect** | Explore type definitions with configurable depth |
| **validate** | Check operations against the schema before executing |
| **execute** | Run GraphQL queries and mutations against the endpoint |

Operations defined as `.graphql` files in `operations/` are also exposed as individual tools.

## Prerequisites

- Docker
- Node.js v18+ (for `npx mcp-remote`)
- VPN access to QA environment
- Auth credentials (JWT + orchard identity headers)

## Quick start

### 1. Configure credentials

```bash
cp .env.example .env
# Fill in your auth token and identity headers
```

Get credentials from browser DevTools (Network tab) on any QA suite app. The JWT expires every ~20 minutes.

### 2. Generate the schema (if not already present)

QA introspection only requires the `apollographql-client-name` header (no auth needed):

```bash
curl -s -X POST "https://qa-graphql-router.theorchard.io/graphql" \
  -H "Content-Type: application/json" \
  -H "apollographql-client-name: frontend-insights" \
  -d '{"query":"{ __schema { queryType { name } mutationType { name } subscriptionType { name } types { kind name description fields(includeDeprecated: true) { name description args { name description type { ...TypeRef } defaultValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { name description type { ...TypeRef } defaultValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } directives { name description locations args { name description type { ...TypeRef } defaultValue } } } } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } }"}' \
  > schema-introspection.json

npx -y graphql-introspection-json-to-sdl schema-introspection.json > schema.graphql
```

Remove any npm warning lines from the top of `schema.graphql` if present.

### 3. Start the MCP server

```bash
docker run -d --rm --name apollo-mcp -p 8000:8000 \
  --env-file .env \
  -v $(pwd)/mcp.yaml:/config.yaml \
  -v $(pwd)/operations:/operations \
  -v $(pwd)/schema.graphql:/schema.graphql \
  ghcr.io/apollographql/apollo-mcp-server:v1.11.0 /config.yaml
```

Verify it's running:

```bash
docker logs apollo-mcp
# Should show: "Indexed 1266 types" and "Starting MCP server in Streamable HTTP mode"
```

### 4. Connect Claude Code

```bash
claude mcp add apollo-mcp -- npx mcp-remote http://127.0.0.1:8000/mcp
```

Start a new Claude Code session — the GraphQL tools will be available.

## Adding operations

Create `.graphql` files in `operations/`. Each file becomes an MCP tool. Use `#` comments for tool descriptions:

```graphql
# operations/GetArtistProfile.graphql

# Look up an artist's profile by ID.
# Returns name, label associations, and basic metadata.
query GetArtistProfile($artistId: ID!) {
  artist(id: $artistId) {
    id
    name
    labels {
      name
    }
  }
}
```

Files hot-reload — no restart needed.

## Architecture

```
Claude Code
    │
    ├── npx mcp-remote ──► Apollo MCP Server (Docker, port 8000)
    │                            │
    │                            ├── schema.graphql (local, 19K lines SDL)
    │                            ├── operations/*.graphql (local tool definitions)
    │                            │
    │                            └──► QA Apollo Router
    │                                    │
    │                                    ├── graphql-analytics
    │                                    ├── graphql-knowledge
    │                                    ├── graphql-user
    │                                    ├── graphql-account
    │                                    └── ... (16 subgraphs)
```

## Subgraphs

abacus, account, analytics, audience, collaborator, content-review, distribution, knowledge, knowledge-search, neighbouring-rights, participant, product, publishing, sr-delivery, tax-payment, user

## Known limitations

- **JWT expiration**: QA tokens expire every ~20 minutes. Refresh by copying new headers from browser DevTools.
- **Numeric header workaround**: `orchard-profile-id` is hardcoded in `mcp.yaml` because Apollo MCP Server's env var expansion doesn't preserve string typing for numeric values.
- **No GraphOS**: This setup uses a locally introspected schema. To use Apollo Studio features (operation collections, uplink), you'd need `APOLLO_KEY` and `APOLLO_GRAPH_REF`.

## Stopping

```bash
docker stop apollo-mcp
```

## References

- [Apollo MCP Server docs](https://www.apollographql.com/docs/apollo-mcp-server)
- [graphql-router repo](https://github.com/theorchard/graphql-router)
- [Techweek Workshop: Local Router Setup](https://www.notion.so/10397177520f80b78f62d6f2e7e5125e)
- [Testing Insights with local router](https://www.notion.so/32d97177520f808ea35fc903a1595dbf)
