Version: 1.0.0
Release Date: 2025-10-14
Author: Simon Tin-Yul Kok
Production Status: ✅ Ready for Local Use
A security-focused Model Context Protocol (MCP) server providing secure, read-only access to the KnowBe4 GraphQL API for Claude Desktop.
🏠 Deployment Model: This is a local desktop tool designed exclusively for personal use with Claude Desktop. Not intended for cloud or multi-tenant deployment.
This MCP server combines fastmcp and gql to provide:
- Read-only GraphQL query execution
- 92+ pre-optimized queries with caching
- Smart query router with 86% pattern match success rate
- Interactive query discovery with clarifying questions
- Multi-strategy PII field filtering and privacy controls
- Comprehensive audit and conversation logging
- Query complexity validation (150-line limit)
- Mutation blocking for safety
- Rate limiting (100 queries/60 seconds)
- Query size limits (100KB max)
- Python 3.10 or higher
- KnowBe4 Diamond-level account
- KnowBe4 Product API Key
- Claude Desktop application
-
Install dependencies
pip install -r setup/requirements.txt
-
Configure environment
cp config/.env.example .env
Edit
.env
and set:GRAPHQL_ENDPOINT
- Your KnowBe4 GraphQL endpoint (see regions below)GRAPHQL_API_KEY
- Your KnowBe4 Product API Key from Partner Settings
-
Download GraphQL schema
The schema is required but not included in the repository for security.
Quick method:
python setup/download_schema.py
Manual method: See docs/SETUP_SCHEMA.md for detailed instructions.
-
Test the server
python mcp-server/main.py
You should see:
Server initialized successfully
Press Ctrl+C to stop.
-
Locate your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
-
Add this server configuration (see
config/claude_desktop_config.json.example
):
{
"mcpServers": {
"knowbe4-graphql": {
"command": "python",
"args": ["/absolute/path/to/mcp-server-knowbe4-graphql-api/mcp-server/main.py"],
"env": {
"GRAPHQL_ENDPOINT": "https://training.knowbe4.com/graphql",
"GRAPHQL_API_KEY": "your_api_key_here",
"GRAPHQL_SCHEMA_PATH": "/absolute/path/to/mcp-server-knowbe4-graphql-api/config/schema.json"
},
"alwaysAllow": ["*"]
}
}
}
Important: Use absolute paths, not relative paths.
By default, Claude Desktop asks for confirmation before executing each tool. To avoid repeated confirmation prompts, add the alwaysAllow
configuration:
Option 1: Approve all tools (simplest)
"alwaysAllow": ["*"]
Option 2: Approve specific tools
"alwaysAllow": [
"query_graphql",
"get_quick_query",
"get_schema_info",
"list_quick_queries",
"discover_queries",
"suggest_query_for_question",
"auto_answer",
"get_server_status",
"clear_cache"
]
This is safe for this MCP server because:
- ✅ All operations are read-only (no mutations allowed)
- ✅ No file system writes or dangerous operations
- ✅ Built-in security controls (PII filtering, rate limiting, query validation)
- ✅ Designed for local desktop use only
Restart Claude Desktop to load the MCP server.
In Claude Desktop, try:
"Can you check the status of the KnowBe4 GraphQL server?"
Claude should respond using the get_server_status
tool.
Then try:
"Who are my highest risk users?"
Claude will use the get_quick_query
tool to fetch this data quickly.
Choose the appropriate endpoint for your region:
Region | Endpoint |
---|---|
United States | https://training.knowbe4.com/graphql |
Europe | https://eu.knowbe4.com/graphql |
Canada | https://ca.knowbe4.com/graphql |
United Kingdom | https://uk.knowbe4.com/graphql |
Germany | https://de.knowbe4.com/graphql |
Execute custom read-only GraphQL queries.
query_graphql(
query="""
query GetUsers {
users(first: 10) {
nodes { id firstName lastName }
}
}
"""
)
Execute pre-optimized queries (faster, cached).
# Get tenant info (cached for 5 min)
get_quick_query(query_name="TENANT_INFO")
# Find user by name
get_quick_query(
query_name="FIND_USER_TEMPLATE",
variables={"searchTerm": "John"}
)
List all available pre-optimized queries.
Discover available queries for a topic and get clarifying questions.
When users make vague requests like "show me training stuff", this tool helps Claude understand what's available and ask clarifying questions to narrow down the request.
# User says: "Show me training stuff"
discover_queries(topic="training")
# Returns: Available training queries and suggested clarifying questions
# Supported topics:
# - training, users, security, phishing, dashboard, groups
# - audit, templates, enrollments, account
How it helps:
- Prevents incorrect query selection
- Improves user experience with clarifying questions
- Makes vague requests more precise
- Shows all available options for a topic
Automatically analyze a user question and suggest the best query to use.
Uses pattern matching to instantly identify the right query for 86% of common questions, eliminating trial-and-error.
# User asks: "Which managers haven't completed their training?"
suggest_query_for_question("Which managers haven't completed their training?")
# Returns:
# {
# "suggested_query": "INCOMPLETE_ENROLLMENTS_TEMPLATE",
# "confidence": "high",
# "variables_needed": ["campaignId"],
# "workflow": ["1. Get campaigns", "2. Find campaign ID", "3. Use template"],
# "fallback_queries": [...]
# }
Benefits:
- 86% pattern match success rate for common questions
- Immediate query suggestion with confidence level
- Step-by-step workflow for complex queries
- Fallback suggestions if primary query doesn't work
- Reduces 9 queries to 1-2 queries (78-89% reduction)
get_schema_info()
- Get schema metadata and security settingsget_schema_type_info(type_name)
- NEW Discover correct field names for any GraphQL typeget_server_status()
- Check server health, configuration, and cache statsset_pii_mode(enabled)
- Toggle PII field access (disabled by default)add_blocked_field(field_name)
- Add custom field blockingremove_blocked_field(field_name)
- Remove field from block list
clear_cache(query_name)
- Clear query cache (all or specific query)
92+ ready-to-use queries organized by category:
Account & Tenant:
TENANT_INFO
- Comprehensive tenant/account informationSECURITY_SETTINGS
- Account security settings
User Management:
ACTIVE_USER_COUNT
- Count of active usersALL_ACTIVE_USERS
- List all active usersHIGH_RISK_USERS
- Users with highest risk scoresFIND_USER_TEMPLATE
- Find users by search term (requiressearchTerm
)USER_DETAILS_TEMPLATE
- Detailed user info (requiresuserId
)
Campaigns:
ACTIVE_PHISHING_CAMPAIGNS
- Active phishing campaignsACTIVE_TRAINING_CAMPAIGNS
- Active training campaignsLOW_COMPLETION_TRAINING
- Training with completion stats
Enrollments:
INCOMPLETE_ENROLLMENTS_TEMPLATE
- Incomplete enrollments (requirescampaignId
)USER_ENROLLMENTS_TEMPLATE
- User enrollments (requiresuserId
)
Groups & Risk:
ALL_GROUPS
- List all groupsGROUPS_WITH_RISK_SCORES
- Groups with risk dataORGANIZATION_RISK_SCORE
- Organization-wide risk metricsINDUSTRY_BENCHMARKS
- Compare to industry benchmarks
Audit:
RECENT_AUDIT_LOGS
- Recent audit entries (last 7 days)
See QUERY_LIBRARY_USAGE.md for complete documentation.
Security Design:
- ✅ Runs locally on your machine with Claude Desktop
- ✅ Read-only operations (all mutations blocked)
- ✅ Multi-strategy PII field filtering
- ✅ Rate limiting (100 queries/60 seconds)
- ✅ Comprehensive audit logging (local files)
- ✅ API key stored securely in
.env
(gitignored) - ✅ No telemetry or external data transmission (except to KnowBe4 API)
Privacy:
- ✅ Conversation logging disabled by default
- ✅ All sensitive data hashed in audit logs
- ✅ Logs stored locally on your machine
- ✅ Process-isolated (each Claude Desktop instance = separate process)
By default, queries containing PII fields are blocked:
- email, emailAddress
- phoneNumber, phone
- address, streetAddress
- dateOfBirth, ssn, passport
- creditCard, bankAccount
Enable PII mode only when necessary: set_pii_mode(true)
All mutations are blocked at query validation level.
Queries are limited to 150 lines to comply with KnowBe4 API limits.
All queries are logged to logs/audit/audit_YYYYMMDD.jsonl
with:
- Timestamp and session ID
- Query hash and preview
- Response hash and size
- Duration and status
- PII mode state
Logs are in JSON Lines format for easy SIEM integration.
User interactions are logged to logs/conversation/conversations_YYYYMMDD.jsonl
with:
- Complete conversation flow
- Original user questions (when provided via
user_question
parameter) - Full response content (complete answers for analysis)
- Processing steps and tool calls
- Performance metrics
- Success/error tracking
The query_graphql
and get_quick_query
tools accept an optional user_question
parameter to capture the original user's question for better analytics. This helps track what users are actually asking vs. how the system interprets it.
Privacy Note: Conversation logs store full responses (not just hashes) to enable comprehensive analysis. Ensure logs are stored securely with appropriate access controls and retention policies.
Use these logs for data-driven improvements. See ANALYZING_LOGS.md for analysis guide.
- Cached (5 minutes): Non-parameterized queries (TENANT_INFO, ALL_GROUPS, etc.)
- Not Cached: Parameterized queries (user searches, specific IDs)
- Automatic Invalidation: Cache expires after 5 minutes
Query Type | First Run | Subsequent Runs |
---|---|---|
TENANT_INFO | 1-2s | <100ms (cached) |
HIGH_RISK_USERS | 2-3s | <100ms (cached) |
ALL_GROUPS | 1-2s | <100ms (cached) |
# After making changes via KnowBe4 UI
clear_cache(query_name="ALL_USERS")
# After bulk user import
clear_cache() # Clear all
# Before critical reports
get_quick_query(query_name="TENANT_INFO", use_cache=False)
-
Check configuration path:
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json
-
Verify paths are absolute in the config file
-
Restart Claude Desktop after any config changes
-
Check Claude logs:
tail -f ~/Library/Logs/Claude/mcp-server-knowbe4-graphql.log
"Schema file not found"
- Download the GraphQL schema and save as
schema.json
"GRAPHQL_API_KEY environment variable is required"
- Check your
.env
file or Claude Desktop config has the API key set
"Query exceeds complexity limit"
- Reduce query to 150 lines or fewer
- Remove unnecessary fields or use pagination
"Mutations are not allowed"
- This server is read-only; mutations are blocked for safety
"Query contains blocked PII fields"
- PII mode is disabled by default
- Ask Claude to enable PII mode or remove specific fields
"Field doesn't exist on type"
- GraphQL field names were guessed incorrectly
- Use
get_schema_type_info(type_name)
to discover correct field names - Example:
get_schema_type_info("PhishingCampaign")
shows all available fields - Tip: Claude should always check the schema before writing custom queries
If you get permission errors:
-
Check write access to logs directory:
mkdir -p logs/audit logs/conversation && touch logs/audit/test && rm logs/audit/test && echo "OK"
-
Check OneDrive sync status if using synced folders
-
Use non-synced directory for better performance by setting absolute paths in
.env
:AUDIT_LOG_DIR=/var/log/knowbe4/audit CONVERSATION_LOG_DIR=/var/log/knowbe4/conversation
Logs not appearing or going to wrong directory:
-
Check .env configuration:
grep LOG_DIR .env
Should show:
AUDIT_LOG_DIR=logs/audit CONVERSATION_LOG_DIR=logs/conversation
-
Restart Claude Desktop after changing
.env
- the server only loads environment variables at startup -
Check log directories exist:
ls -la logs/audit logs/conversation
-
Verify logs are being written immediately:
- Logs write synchronously to disk after each operation
- If logs only appear after closing Claude Desktop, ensure you've restarted after the latest update
Logs appearing in multiple directories:
- Old logs in
audit_logs/
can be safely deleted after confirming new logs are inlogs/audit/
- The server now correctly uses the configured directory paths
Audit logs:
cat logs/audit/audit_$(date +%Y%m%d).jsonl
Conversation logs:
cat logs/conversation/conversations_$(date +%Y%m%d).jsonl | jq .
Claude Desktop logs (for server errors):
tail -f ~/Library/Logs/Claude/mcp-server-knowbe4-graphql.log
.
├── README.md # This file
├── CLAUDE.md # Architecture and technical reference
├── .env # Environment variables (not committed)
├── mcp-server/ # MCP server application
│ ├── main.py # Server entry point
│ ├── graphql_tools.py # GraphQL execution and validation
│ ├── audit_logger.py # Compliance logging
│ ├── conversation_logger.py # User interaction tracking
│ └── query_library.py # Pre-optimized queries and caching
├── docs/ # Documentation
│ ├── QUERY_LIBRARY_USAGE.md # Complete query documentation
│ └── ANALYZING_LOGS.md # Log analysis guide
├── config/ # Configuration files
│ ├── .env.example # Environment template
│ ├── claude_desktop_config.json.example # Claude Desktop config template
│ ├── mcp.json # MCP config example
│ ├── schema.json # KnowBe4 GraphQL schema (user-provided, not in git)
│ └── schema.json.example # Schema download instructions
├── setup/ # Setup and initialization
│ ├── requirements.txt # Python dependencies
│ ├── pyproject.toml # Project metadata
│ └── download_schema.py # Schema download helper
└── tests/ # Test files
├── conftest.py # Pytest fixtures
├── test_*.py # Unit test suites
└── diagnose.py # Diagnostic tool
# Run all unit tests
pytest
# Run tests with coverage
pytest --cov=. --cov-report=html
# Run diagnostics
python3 tests/diagnose.py
black .
ruff check .
This server is designed to meet:
- SOC 2 audit requirements
- ISO 27001 security standards
- Internal security policies
Features include:
- Session-scoped secrets (no persistent storage)
- Comprehensive audit trails
- Field-level access controls
- Query validation and sanitization
- README.md - This file (main documentation, quick start, usage guide)
- CLAUDE.md - Architecture, technical reference, and development guide (for Claude Code)
- CHANGELOG.md - Version history and completed improvements
- LICENSE.md - MIT License and copyright information
Setup & Configuration:
- docs/SETUP_SCHEMA.md - GraphQL schema download instructions
- docs/DEPENDENCIES.md - Dependency management and security updates
Usage & Reference:
- docs/QUERY_LIBRARY_USAGE.md - Complete query library reference with 92+ pre-optimized queries
- docs/FIELD_REFERENCE.md - KnowBe4 GraphQL field reference and common patterns
- docs/ANALYZING_LOGS.md - Log analysis and improvement guide
Development:
- docs/TESTING.md - Testing guide (see also: tests/README.md for comprehensive guide)
- docs/REPOSITORY_STRUCTURE.md - Project structure and code organization
Security:
- docs/SECURITY_REVIEW.md - Comprehensive security analysis and controls
- KnowBe4 GraphQL API Documentation
- Model Context Protocol Specification
- fastmcp Documentation
- Claude Desktop MCP Guide
MIT License - See LICENSE file for details
This server requires a KnowBe4 Diamond-level account. APIs have limited support from KnowBe4. Deletions via the API (if mutations were enabled) are permanent and cannot be undone.