This is a thin wrapper around Apollo MCP Server configured specifically for DoControl's authentication flow.
Apollo MCP Server is a Model Context Protocol server that exposes GraphQL operations as MCP tools. It provides a standard way for AI models to access and orchestrate GraphQL APIs.
For full documentation about Apollo MCP Server capabilities, see the official documentation.
This wrapper handles DoControl's OAuth token refresh flow automatically:
- On-Demand Refresh: Tokens are refreshed automatically before each request when needed
- Smart Detection: Refreshes if token has less than 2 minutes remaining (out of 5-minute lifetime)
- Config Update: Fresh tokens are written back to the config file's auth section
- Shared Headers: Tokens are updated in both config file and in-memory headers atomically
- No Background Tasks: Refresh happens synchronously when needed, not in background
- GraphQL Requests: All operations use the current valid access token
This approach ensures:
- ✅ No wasted refreshes - Only refresh when token is actually needed
- ✅ No startup delay - Server starts instantly without initial token verification
- ✅ Thread-safe - Global token manager accessible from all request handlers
- ✅ Reliable - Synchronous refresh ensures token is valid before each request
Note: DoControl tokens have a 5-minute lifetime. The server refreshes tokens on-demand before executing requests to ensure they're always valid.
Required environment variables (must be in MCP client config):
# DoControl Token Refresh (Required)
DC_TOKEN_REFRESH_ENABLED="true"
DC_REFRESH_TOKEN="eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ..." # Encrypted refresh token (see Token Format below)
DC_REFRESH_URL="https://auth.prod.docontrol.io/refresh"Optional environment variables (recommended to move to config file):
# GraphQL Endpoint (OPTIONAL - recommended to put in config.yaml as 'endpoint')
DC_GRAPHQL_ENDPOINT="https://apollo-gateway-v4-api.prod.docontrol.io/graphql"
# Apollo GraphOS API Key (OPTIONAL - recommended to put in config.yaml)
DC_API_KEY="service:docontrol-api:your-apollo_key"
# Graph Reference Override (OPTIONAL - defaults to "docontrol-api@current")
# DC_GRAPH_REF="docontrol-api@current"💡 Recommendation: Move DC_GRAPHQL_ENDPOINT and DC_API_KEY to your config file (see below) to keep all non-sensitive configuration in one place.
Create a YAML configuration file (e.g., config.yaml):
# GraphQL endpoint URL
endpoint: https://apollo-gateway-v4-api.prod.docontrol.io/graphql
# Transport configuration (stdio for MCP)
transport:
type: stdio
# Authentication headers (automatically managed by token refresh)
headers:
Authorization: Bearer <token-will-be-auto-refreshed>
# Apollo GraphOS integration
graphos:
apollo_graph_ref: docontrol-api@current
apollo_key: service:docontrol-api:your-apollo_key
# Mutation mode: "none" (read-only), "all" (full access)
allow-mutations: none
# Operation source: use introspection to discover operations
operations:
- introspect
# Logging configuration
logging:
level: error
format: plain
color: false
# Introspection tools configuration
introspection:
execute:
enabled: true # Enable execute tool to run queries
introspect:
enabled: true # Enable introspect tool for schema discovery
minify: true # Minify schema output
search:
enabled: true # Enable search tool for finding types
minify: true # Minify search results
index_memory_bytes: 50000000 # Memory limit for search index
leaf_depth: 1 # Depth for leaf type expansion
validate:
enabled: true # Enable validate tool for query validationCore Settings:
endpoint: The DoControl GraphQL API endpointtransport.type:stdiofor MCP communication (required for MCP clients)
Authentication:
headers.Authorization: Automatically updated by token refresh system- The token in this field is managed by the server - it will be overwritten on startup and during refresh
- You can put any placeholder value here (e.g.,
Bearer placeholder) - it will be replaced with a valid token
GraphOS Integration:
apollo_graph_ref: Your graph reference in Apollo Studio (e.g.,docontrol-api@current)apollo_key: Your Apollo Studio API key for schema registry access
Security:
allow-mutations: Set tononefor read-only access,allto allow mutations
Operations:
introspect: Use introspection to discover all queries and mutations automatically- Alternative:
uplinkto use Apollo Studio operation collections
Introspection Tools: The server provides 4 MCP tools when introspection is enabled:
-
execute: Run GraphQL queries and mutations- Validates operation syntax
- Executes against the live endpoint
- Returns JSON results
-
introspect: Explore the GraphQL schema- Get type information with hierarchy
- Discover fields, arguments, and descriptions
- Navigate relationships between types
-
search: Find types in the schema by name- Fuzzy search across all types
- Returns matching type definitions
- Useful for discovery
-
validate: Validate GraphQL operations before execution- Syntax checking
- Schema validation
- Helpful for debugging
Note: The apollo_key can reference environment variables using ${DC_API_KEY} syntax, but it's recommended to put the actual value directly in the config file.
Note: The Authorization header is automatically managed by the token refresh system. You don't need to manually update it. The server will:
- Read
DC_REFRESH_TOKENfrom the environment on startup - Call the refresh endpoint to get a fresh access token
- Write the access token to
headers.Authorizationin the config file - Automatically refresh the token every ~4 minutes (before the 5-minute expiration)
| Setting | Environment Variable | Config File | Recommendation |
|---|---|---|---|
| Refresh Token | DC_REFRESH_TOKEN |
❌ Not supported | ✅ Keep in env (security) |
| Refresh URL | DC_REFRESH_URL |
❌ Not supported | ✅ Keep in env |
| GraphQL Endpoint | DC_GRAPHQL_ENDPOINT |
endpoint |
✅ Move to config (cleaner) |
| Apollo API Key | DC_API_KEY |
graphos.apollo_key |
✅ Move to config (cleaner) |
| Graph Ref | DC_GRAPH_REF |
graphos.apollo_graph_ref |
Minimal MCP Client Config (~/.cursor/mcp.json):
{
"mcpServers": {
"docontrol-mcp-server": {
"command": "/usr/local/bin/dc-mcp-server",
"args": ["/path/to/config.yaml"],
"env": {
"DC_TOKEN_REFRESH_ENABLED": "true",
"DC_REFRESH_TOKEN": "YOUR_REFRESH_TOKEN",
"DC_REFRESH_URL": "https://auth.prod.docontrol.io/refresh",
"RUST_LOG": "info",
"RUSTLS_SYSTEM_CERT_ROOT": "1"
}
}
}
}Complete Config File (config.yaml):
endpoint: https://apollo-gateway-v4-api.prod.docontrol.io/graphql
transport:
type: stdio
headers:
Authorization: Bearer placeholder # Auto-updated
graphos:
apollo_graph_ref: docontrol-api@current
apollo_key: service:docontrol-api:YOUR_APOLLO_KEY # ← Put DC_API_KEY here
allow-mutations: none
operations:
- introspectBenefits of this approach:
- ✅ Sensitive tokens stay in environment variables (more secure)
- ✅ Non-sensitive config (API keys, endpoints) in config file (easier to manage)
- ✅ Config file can be version controlled (without secrets)
- ✅ Easier to update non-sensitive settings without restarting MCP client
- ✅ No duplication -
endpointandDC_GRAPHQL_ENDPOINTare the same, so just use config file
Option A: Download from Releases
# macOS (Apple Silicon)
curl -L https://github.com/docontrol-io/dc-mcp-server/releases/latest/download/dc-mcp-server-macos-aarch64.tar.gz | tar xz
chmod +x dc-mcp-server
# Linux
curl -L https://github.com/docontrol-io/dc-mcp-server/releases/latest/download/dc-mcp-server-linux-x86_64.tar.gz | tar xz
chmod +x dc-mcp-server
# Move to a permanent location
sudo mv dc-mcp-server /usr/local/bin/Option B: Build from Source
git clone https://github.com/docontrol-io/dc-mcp-server.git
cd dc-mcp-server
cargo build --release
sudo cp target/release/dc-mcp-server /usr/local/bin/Create a file named docontrol-config.yaml:
endpoint: https://apollo-gateway-v4-api.prod.docontrol.io/graphql
transport:
type: stdio
headers:
Authorization: Bearer placeholder # Will be auto-updated
graphos:
apollo_graph_ref: docontrol-api@current
apollo_key: service:docontrol-api:YOUR_APOLLO_KEY_HERE
allow-mutations: none
operations:
- introspect
logging:
level: error
format: plain
color: false
introspection:
execute:
enabled: true
introspect:
enabled: true
minify: true
search:
enabled: true
minify: true
validate:
enabled: trueReplace YOUR_APOLLO_KEY_HERE with your actual Apollo Studio API key.
You'll need two secrets from DoControl:
-
Refresh Token (
DC_REFRESH_TOKEN):- Format: Long encrypted JWT string (e.g.,
eyJjdHkiOiJKV1QiLCJlbmMi...) ⚠️ Important: Use therefreshTokenfield from the auth API response, NOT thetokenfield⚠️ Common mistake: Don't paste the entire JSON response - only the refresh token string- This is a long-lived token used to get fresh access tokens
- Keep this secret secure!
- Format: Long encrypted JWT string (e.g.,
-
Apollo API Key (
DC_API_KEY):- Format:
service:docontrol-api:xxxxx - Used to access Apollo Studio for schema registry
- Format:
How to get your refresh token:
# If you have an existing refresh token, get a new one:
curl -X POST https://auth.prod.docontrol.io/refresh \
-H "Content-Type: application/json" \
-d '{"refreshToken":"YOUR_EXISTING_REFRESH_TOKEN"}'
# Response will be:
# {
# "token": "eyJraWQiOiI...", // Access token (expires in 5 min) - DON'T USE THIS
# "expiresIn": 300,
# "refreshToken": "eyJjdHkiOiJKV1QiLCJlbmMi..." // ← Use THIS as DC_REFRESH_TOKEN
# }Copy only the refreshToken value (the long encrypted string) - this is what goes in DC_REFRESH_TOKEN.
For Cursor:
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"dc-mcp-server": {
"command": "/usr/local/bin/dc-mcp-server",
"args": ["/absolute/path/to/docontrol-config.yaml"],
"env": {
"DC_TOKEN_REFRESH_ENABLED": "true",
"DC_REFRESH_TOKEN": "YOUR_REFRESH_TOKEN_HERE",
"DC_REFRESH_URL": "https://auth.prod.docontrol.io/refresh",
"RUST_LOG": "info",
"RUSTLS_SYSTEM_CERT_ROOT": "1"
}
}
}
}For Claude Desktop (macOS):
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"dc-mcp-server": {
"command": "/usr/local/bin/dc-mcp-server",
"args": ["/absolute/path/to/docontrol-config.yaml"],
"env": {
"DC_TOKEN_REFRESH_ENABLED": "true",
"DC_REFRESH_TOKEN": "YOUR_REFRESH_TOKEN_HERE",
"DC_REFRESH_URL": "https://auth.prod.docontrol.io/refresh",
"RUST_LOG": "info",
"RUSTLS_SYSTEM_CERT_ROOT": "1"
}
}
}
}Important Notes:
- Use absolute paths for both the command and config file
- Replace
YOUR_REFRESH_TOKEN_HEREwith your actual refresh token - DO NOT include
DC_API_KEYorDC_GRAPHQL_ENDPOINThere - they should be in your config.yaml file - The
RUSTLS_SYSTEM_CERT_ROOT=1is required for SSL certificate validation
- Cursor: Restart the application or reload the window
- Claude Desktop: Quit and restart the application
In your MCP client, you should see 4 new tools available:
- ✅
execute- Run GraphQL queries - ✅
introspect- Explore the schema - ✅
search- Search for types - ✅
validate- Validate queries
Try asking: "What is the company information?" or "Show me the company details"
For testing and debugging:
export DC_TOKEN_REFRESH_ENABLED="true"
export DC_REFRESH_TOKEN="your-refresh-token"
export DC_REFRESH_URL="https://auth.prod.docontrol.io/refresh"
# Note: DC_GRAPHQL_ENDPOINT and DC_API_KEY should be in your config.yaml file, not as env vars
npx @modelcontextprotocol/inspector dc-mcp-server config.yamlThe server automatically discovers all available GraphQL operations by introspecting the schema:
- Schema Discovery: Introspects the GraphQL endpoint to discover all types and fields
- Tool Generation: Each query and mutation becomes an MCP tool
- Dynamic: Changes to the GraphQL schema are automatically reflected
- No Manual Configuration: No need to maintain operation files
All queries and mutations from the DoControl GraphQL API are automatically available as tools to AI models.
Download the latest release for your platform from the releases page:
- Linux:
dc-mcp-server-linux-x86_64.tar.gz - macOS:
dc-mcp-server-macos-aarch64.tar.gz - Windows:
dc-mcp-server-windows-x86_64.tar.gz
cargo build --release --package dc-mcp-server
cp target/release/dc-mcp-server /usr/local/bin/- Create configuration file (
config.yaml):
endpoint: "https://apollo-gateway-v4-api.prod.docontrol.io/graphql"
operations: introspect
introspection:
query: true
mutation: true-
Get your credentials:
- Refresh Token: From DoControl OAuth flow (secret)
- Apollo Graph Ref: Your graph identifier, e.g.,
docontrol-api@current(internal) - Apollo Key: API key from Apollo Studio (secret)
-
Configure your MCP client with environment variables (see configuration examples above)
-
Start your MCP client - the server handles all authentication and operation discovery automatically!
The AI assistant will have access to all GraphQL queries and mutations from the DoControl API.
All credentials are secrets and should be protected:
- ✅ Never commit credentials to version control
- ✅ Use environment variables for sensitive tokens (
DC_REFRESH_TOKEN) - ✅ Store API keys in config files (
graphos.apollo_key) - easier to manage, can be encrypted at rest - ✅ Store tokens securely - use secret management systems (e.g., 1Password, AWS Secrets Manager)
- ✅ Rotate tokens regularly - follow DoControl security best practices
- ✅ Limit permissions - use read-only tokens when possible (set
allow-mutations: none)
Secrets to protect:
DC_REFRESH_TOKEN- DoControl OAuth refresh token (keep in environment variables)graphos.apollo_key- Apollo Studio API key (can be in config file with proper file permissions)- Config files containing tokens (set appropriate file permissions:
chmod 600 config.yaml)
The server uses an intelligent on-demand token refresh strategy:
- Server Startup: Reads
DC_REFRESH_TOKENfrom environment - No Initial Refresh: Server starts immediately without fetching tokens
- Global Token Manager: TokenManager is initialized and stored globally
- Fast Startup: No blocking network calls during initialization
- Before Each Request: Token manager checks if current token is valid
- Token Expiry Check: Refreshes if less than 2 minutes remaining (out of 5-minute lifetime)
- Synchronous Refresh: If needed, refreshes token before executing the request
- Atomic Updates: Updates both config file and in-memory headers together
- Error Handling: If refresh fails, request proceeds with current token
- DoControl tokens expire after 5 minutes
- Refresh threshold: 2 minutes remaining - ensures token won't expire during request
- First request after startup will always refresh (no initial token)
- Token is reused across multiple requests within the 3-minute window (5min - 2min threshold)
- Proactive refresh prevents mid-request token expiry
- Efficient: Tokens are reused across multiple requests
- Reliable: Token is always validated before use
- Fast Startup: Server is ready instantly
- Thread-Safe: Global static ensures safe concurrent access
- No Background Tasks: Simpler architecture, easier to debug
cargo test --workspacecargo build --releaseEnable debug logging:
RUST_LOG=debug dc-mcp-server config.yamlThis project is based on Apollo MCP Server. For general MCP server features and documentation, refer to the upstream project.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.