Developer Guide
Comprehensive guide for developing, extending, and customizing the MCP Context Provider.
Table of Contents
- Development Setup
- Server Architecture
- Creating Custom Contexts
- Extending the Server
- Testing
- Debugging
- Deployment
- API Reference
Development Setup
Prerequisites
- Python 3.8+
- Claude Desktop
- Basic understanding of MCP (Model Context Protocol)
- JSON and regex knowledge
Installation
Clone and setup:
git clone https://github.com/your-repo/MCP-Context-Provider.git cd MCP-Context-Provider python -m venv venv source venv/bin/activate # or venv\Scripts\activate on Windows pip install mcpDevelopment dependencies:
pip install pytest black flake8 mypyIDE Setup:
- Install Python extension
- Configure linting and formatting
- Set up debugging for Python scripts
Server Architecture
Core Components
MCP-Context-Provider/
├── context_provider_server.py # Main MCP server
├── contexts/ # Context files directory
│ ├── dokuwiki_context.json
│ ├── terraform_context.json
│ └── ...
├── claude_desktop_config_with_context.json
└── docs/
Class Structure
class ContextProvider:
def __init__(self, config_dir: str)
def load_all_contexts(self)
def load_context_file(self, file_path: Path)
def get_tool_context(self, tool_name: str)
def get_syntax_rules(self, tool_name: str)
def get_preferences(self, tool_name: str)
def apply_auto_corrections(self, tool_name: str, text: str)
MCP Server Flow
graph TD
A[Claude Desktop Start] --> B[Load MCP Server]
B --> C[Initialize ContextProvider]
C --> D[Load Context Files]
D --> E[Register MCP Tools]
E --> F[Server Ready]
F --> G[Tool Calls Available]
Tool Registration
The server registers four main tools:
- get_tool_context: Returns full context for a tool
- get_syntax_rules: Returns syntax rules only
- list_available_contexts: Lists all loaded contexts
- apply_auto_corrections: Applies regex corrections to text
Creating Custom Contexts
Step-by-Step Process
1. Identify Tool Requirements
Analyze the target tool to identify:
- Common syntax patterns
- Formatting preferences
- Naming conventions
- Best practices
- Common mistakes to auto-correct
2. Create Context File
Create contexts/{toolname}_context.json:
{
"tool_category": "my_tool",
"description": "Context rules for my custom tool",
"auto_convert": true,
"syntax_rules": {
// Define formatting rules
},
"preferences": {
// Define user preferences
},
"auto_corrections": {
// Define regex corrections
},
"metadata": {
"version": "1.0.0",
"last_updated": "2025-01-08",
"applies_to_tools": ["my_tool:*"]
}
}
3. Define Syntax Rules
Structure syntax rules logically:
{
"syntax_rules": {
"formatting": {
"indent": " ",
"line_ending": "\\n",
"quote_style": "double"
},
"naming": {
"variables": "camelCase",
"functions": "camelCase",
"classes": "PascalCase",
"constants": "UPPER_SNAKE_CASE"
},
"patterns": {
"function_definition": "function {}() {\\n // body\\n}",
"class_definition": "class {} {\\n constructor() {\\n // initialization\\n }\\n}"
}
}
}
4. Add Auto-Corrections
Create regex patterns for common corrections:
{
"auto_corrections": {
"fix_spacing": {
"pattern": "\\s{2,}",
"replacement": " "
},
"standardize_quotes": {
"pattern": "'([^']*)'",
"replacement": "\"$1\""
},
"fix_semicolons": {
"pattern": "([^;])\\n",
"replacement": "$1;\\n"
}
}
}
5. Test the Context
# Test script: test_context.py
from context_provider_server import ContextProvider
def test_my_context():
provider = ContextProvider()
# Test context loading
context = provider.get_tool_context("my_tool")
assert context["tool_category"] == "my_tool"
# Test auto-corrections
input_text = "let x='hello'"
corrected = provider.apply_auto_corrections("my_tool", input_text)
expected = "let x=\"hello\";"
assert corrected == expected
print("All tests passed!")
if __name__ == "__main__":
test_my_context()
Advanced Context Patterns
Conditional Rules
{
"syntax_rules": {
"environment_specific": {
"development": {
"debug_enabled": true,
"logging_level": "debug"
},
"production": {
"debug_enabled": false,
"logging_level": "error"
}
}
}
}
Hierarchical Preferences
{
"preferences": {
"global": {
"encoding": "utf-8",
"line_endings": "lf"
},
"project_specific": {
"web": {
"framework": "react",
"build_tool": "vite"
},
"api": {
"framework": "fastapi",
"database": "postgresql"
}
}
}
}
Multi-Language Support
{
"syntax_rules": {
"languages": {
"javascript": {
"file_extension": ".js",
"comment_style": "// {}",
"block_comment": "/* {} */"
},
"typescript": {
"file_extension": ".ts",
"comment_style": "// {}",
"type_annotations": true
}
}
}
}
Extending the Server
Adding New MCP Tools
- Define the tool:
Tool(
name="my_custom_tool",
description="Description of what the tool does",
inputSchema={
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "First parameter"
}
},
"required": ["param1"]
}
)
- Implement the handler:
@app.call_tool()
async def handle_call_tool(name: str, arguments: dict) -> CallToolResult:
if name == "my_custom_tool":
param1 = arguments.get("param1")
# Your custom logic here
result = process_custom_logic(param1)
return CallToolResult(
content=[TextContent(type="text", text=str(result))]
)
Adding Context Validation
def validate_context_file(file_path: Path) -> bool:
"""Validate context file structure and content"""
try:
with open(file_path, 'r') as f:
context = json.load(f)
# Required fields
required_fields = ['tool_category', 'description']
for field in required_fields:
if field not in context:
print(f"Missing required field: {field}")
return False
# Validate auto_corrections regex patterns
auto_corrections = context.get('auto_corrections', {})
for name, rule in auto_corrections.items():
if 'pattern' in rule:
try:
re.compile(rule['pattern'])
except re.error as e:
print(f"Invalid regex pattern in {name}: {e}")
return False
return True
except Exception as e:
print(f"Error validating context file: {e}")
return False
Custom Context Loaders
class CustomContextLoader:
def load_from_database(self, connection_string: str):
"""Load contexts from database"""
pass
def load_from_api(self, api_endpoint: str):
"""Load contexts from API"""
pass
def load_from_git(self, repo_url: str, branch: str = "main"):
"""Load contexts from Git repository"""
pass
Testing
Unit Tests
# tests/test_context_provider.py
import pytest
from context_provider_server import ContextProvider
class TestContextProvider:
def setup_method(self):
self.provider = ContextProvider("./test_contexts")
def test_load_contexts(self):
assert len(self.provider.contexts) > 0
def test_get_tool_context(self):
context = self.provider.get_tool_context("dokuwiki")
assert context["tool_category"] == "dokuwiki"
def test_apply_auto_corrections(self):
input_text = "# Header"
result = self.provider.apply_auto_corrections("dokuwiki", input_text)
assert "======" in result
Integration Tests
# tests/test_integration.py
import asyncio
import json
from context_provider_server import app
async def test_mcp_tools():
"""Test MCP tool integration"""
# Test list_tools
tools = await app.list_tools()
assert len(tools) >= 4
# Test tool calls
result = await app.call_tool("list_available_contexts", {})
contexts = json.loads(result.content[0].text)
assert isinstance(contexts, list)
Performance Tests
import time
from context_provider_server import ContextProvider
def test_context_loading_performance():
"""Test context loading performance"""
start_time = time.time()
provider = ContextProvider()
load_time = time.time() - start_time
assert load_time < 1.0, f"Context loading took {load_time:.2f}s"
def test_regex_performance():
"""Test auto-correction regex performance"""
provider = ContextProvider()
large_text = "Sample text " * 1000
start_time = time.time()
result = provider.apply_auto_corrections("dokuwiki", large_text)
correction_time = time.time() - start_time
assert correction_time < 0.1, f"Auto-corrections took {correction_time:.2f}s"
Debugging
Enable Debug Mode
Environment variable:
export DEBUG_MODE=trueClaude Desktop config:
{ "env": { "DEBUG_MODE": "true" } }
Logging
Add logging to the server:
import logging
# Configure logging
logging.basicConfig(
level=logging.DEBUG if os.getenv('DEBUG_MODE') == 'true' else logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class ContextProvider:
def load_context_file(self, file_path: Path):
logger.debug(f"Loading context file: {file_path}")
# ... rest of method
Common Debug Scenarios
Context not loading:
def debug_context_loading(): provider = ContextProvider() print(f"Loaded contexts: {list(provider.contexts.keys())}") for name, context in provider.contexts.items(): print(f" {name}: {context.get('description', 'No description')}")Regex not working:
def debug_regex_patterns(tool_name: str, text: str): provider = ContextProvider() context = provider.get_tool_context(tool_name) auto_corrections = context.get('auto_corrections', {}) for name, rule in auto_corrections.items(): pattern = rule['pattern'] replacement = rule['replacement'] import re matches = re.findall(pattern, text) if matches: print(f"Rule '{name}' matched: {matches}") else: print(f"Rule '{name}' no matches")
Remote Debugging
For Claude Desktop integration debugging:
# Add to server startup
if os.getenv('DEBUG_MODE') == 'true':
import pdb
pdb.set_trace() # Breaks execution for debugging
Deployment
Development Deployment
Local testing:
python context_provider_server.py # Test with sample MCP callsClaude Desktop integration:
- Update configuration file
- Restart Claude Desktop
- Test context loading
Production Deployment
Package preparation:
# Create requirements.txt pip freeze > requirements.txt # Create setup script python setup.py sdist bdist_wheelDistribution:
# Create distribution package zip -r mcp-context-provider.zip . -x "*.git*" "*__pycache__*"Installation script:
#!/bin/bash # install.sh python -m venv venv source venv/bin/activate pip install -r requirements.txt echo "Installation complete!" echo "Update your Claude Desktop config with:" echo " \"cwd\": \"$(pwd)\""
Configuration Management
For multiple environments:
# config.py
import os
class Config:
CONTEXT_DIR = os.getenv('CONTEXT_CONFIG_DIR', './contexts')
DEBUG_MODE = os.getenv('DEBUG_MODE', 'false').lower() == 'true'
AUTO_LOAD = os.getenv('AUTO_LOAD_CONTEXTS', 'true').lower() == 'true'
class DevelopmentConfig(Config):
DEBUG_MODE = True
CONTEXT_DIR = './contexts/development'
class ProductionConfig(Config):
DEBUG_MODE = False
CONTEXT_DIR = './contexts/production'
API Reference
ContextProvider Class
Methods
__init__(config_dir: str = "./contexts"): Initialize with context directoryload_all_contexts(): Load all context files from directoryget_tool_context(tool_name: str) -> Dict[str, Any]: Get full context for toolget_syntax_rules(tool_name: str) -> Dict[str, Any]: Get syntax rules onlyget_preferences(tool_name: str) -> Dict[str, Any]: Get preferences onlyapply_auto_corrections(tool_name: str, text: str) -> str: Apply corrections to text
MCP Tools
get_tool_context
- Input:
{"tool_name": "string"} - Output: Complete context object as JSON
- Usage: Get all rules and preferences for a tool
get_syntax_rules
- Input:
{"tool_name": "string"} - Output: Syntax rules object as JSON
- Usage: Get formatting and conversion rules
list_available_contexts
- Input:
{} - Output: Array of context category names
- Usage: Discover available contexts
apply_auto_corrections
- Input:
{"tool_name": "string", "text": "string"} - Output: Corrected text
- Usage: Apply regex-based corrections
Error Handling
All MCP tools return errors in this format:
{
"content": [{"type": "text", "text": "Error: description"}],
"isError": true
}
Common error scenarios:
- Missing tool_name parameter
- Tool context not found
- Invalid regex patterns
- File loading errors
This completes the comprehensive developer guide for the MCP Context Provider.