System Integration Guide: Understanding the Complete Architecture¶
How all components work together to deliver MCP database capabilities
Overview¶
This document brings together all the individual components covered in the Developer Guide to explain how the mcp_ohmy_sql system works as a unified whole. Understanding this integration is essential for maintainers who need to add features, fix bugs, or extend the system to support new database types.
The mcp_ohmy_sql architecture follows a layered, modular design where each component has a specific responsibility, yet all components work together seamlessly to deliver database access through the Model Context Protocol (MCP).
Architecture Summary:
User Request → MCP Tools → Adapters → Configuration + Database Operations
↘ ↙
SDK Utilities + db/ Module
(Per-Database) (Schema Processing)
System Components Overview¶
Let’s revisit how each component fits into the larger system:
- 1. Database Metadata Module (Database Metadata Module)
Foundation layer that extracts and processes database schemas using the three-layer Model-Encoder-Extractor pattern.
- 2. Per-SDK Utilities (Per-SDK Utilities)
Database-specific connection and query utilities that wrap external SDKs (SQLAlchemy, boto3, etc.).
- 3. Configuration System (Configuration System)
Hierarchical JSON-based configuration that defines databases, schemas, and access rules.
- 4. Adapter System (Adapters)
Integration bridge that combines configuration with database operations to create MCP tools.
- 5. Real Database Testing (Real Database Testing Strategy)
Comprehensive testing strategy using actual databases to ensure reliability.
Complete Data Flow: From User Request to Database Response¶
Understanding how a typical request flows through the entire system helps clarify where to make changes for different types of modifications.
Example: “Get schema details for database ‘ecommerce’”
1. MCP Client Request
↓
2. MCP Server (tools.py)
- Receives tool call: get_schema_details(database_id="ecommerce")
- Forwards to adapter layer
↓
3. Adapter Layer (adapter/tool_adapter.py)
- Validates database_id exists in configuration
- Retrieves Database configuration object
- Determines database type (postgres, sqlite, aws_redshift, etc.)
↓
4. Configuration Resolution (config/define.py)
- Loads Database object with connection details
- Gets Schema objects with filtering rules
- Validates all configuration constraints
↓
5. Database Connection (sdk utilities + db/ extractors)
- SDK utility establishes connection (sa/, aws/, etc.)
- db/ extractor queries database metadata
- Three-layer processing: raw data → models → encoded output
↓
6. Result Processing (adapter/tool_adapter.py)
- Formats encoded schema as MCP tool response
- Adds performance timing information
- Returns structured JSON to MCP client
Where to Make Changes: Developer Decision Tree¶
When modifying the system, use this decision tree to identify which components need changes:
- Adding a New Database Type (e.g., MongoDB support)
Create new SDK utility module:
mcp_ohmy_sql/mongodb/(Per-SDK Utilities)Add database-specific subdirectory:
mcp_ohmy_sql/db/mongodb/(Database Metadata Module)Implement three-layer pattern: models, encoders, extractors (Model-Encoder-Extractor)
Add connection configuration:
mcp_ohmy_sql/config/mongodb.py(Configuration System)Update adapter logic:
mcp_ohmy_sql/adapter/(Adapters)Add test database provisioning (Real Database Testing Strategy)
- Adding a New MCP Tool (e.g., execute_insert_statement)
Add tool implementation:
mcp_ohmy_sql/adapter/tool_adapter.py(Adapters)Add MCP wrapper:
mcp_ohmy_sql/tools.pyUpdate configuration if new settings needed (Configuration System)
Add integration tests (Real Database Testing Strategy)
- Modifying Schema Encoding (e.g., change LLM format)
Update encoder functions:
mcp_ohmy_sql/db/*/schema_2_encoder.py(Model-Encoder-Extractor)Update model definitions if needed:
mcp_ohmy_sql/db/*/schema_1_model.pyVerify adapter layer compatibility:
mcp_ohmy_sql/adapter/(Adapters)Update relevant unit tests
- Adding Configuration Options (e.g., query timeout settings)
Update configuration models:
mcp_ohmy_sql/config/define.py(Configuration System)Update adapters to use new settings:
mcp_ohmy_sql/adapter/(Adapters)Update SDK utilities if connection behavior changes (Per-SDK Utilities)
Add configuration validation tests
- Performance Optimization (e.g., caching, connection pooling)
Identify bottleneck location using the data flow diagram above
For connection issues: modify SDK utilities (Per-SDK Utilities)
For metadata extraction: optimize db/ extractors (Database Metadata Module)
For encoding: optimize encoders (Model-Encoder-Extractor)
Add performance test cases (Real Database Testing Strategy)
- Bug Fixes
Identify which layer contains the bug using error traces
Write a failing test that reproduces the issue
Fix the bug in the appropriate component
Ensure fix doesn’t break integration between components
Component Integration Patterns¶
- Configuration → Database Operations
The
Databaseobject contains all information needed to establish connections and perform operations. Adapters convert configuration objects into executable database calls.# Configuration drives database operations database_config = config.databases_mapping["my_db"] connection = database_config.connection.create_connection() schemas = extract_all_schemas(connection, database_config.schemas)
- SDK Utilities ↔ db/ Module
SDK utilities handle connection management and low-level operations, while the db/ module processes metadata. They work together but remain independent.
# SDK utility provides connection, db/ module processes metadata engine = sqlalchemy_connection.sa_engine # SDK utility extractor = RelationalExtractor() # db/ module schema_info = extractor.extract_schema_info(engine, schema_config)
- Adapters as Integration Hub
Adapters orchestrate all other components without containing business logic themselves. They handle error cases and coordinate complex operations.
# Adapter coordinates but delegates actual work def get_schema_details(database_id: str) -> dict: config = load_configuration() # Configuration db_config = config.databases_mapping[database_id] # Configuration connection = create_connection(db_config) # SDK Utility schema_info = extract_schemas(connection) # db/ Module return format_response(schema_info) # Adapter logic
Testing Integration Points¶
The Real Database Testing Strategy ensures all integration points work correctly with actual databases. Key integration tests verify:
- Configuration → Database Connection
Test that configuration objects successfully establish connections to real databases.
- Schema Extraction → Encoding
Test that extracted metadata is correctly encoded into AI-friendly formats.
- Adapter Coordination
Test that adapters correctly orchestrate all components for complete tool functionality.
- Cross-Database Consistency
Test that the same operations work consistently across different database types.
Error Handling Integration¶
Errors can occur at any integration point. The system handles errors systematically:
- Configuration Errors (Invalid JSON, missing fields)
Caught during configuration loading with detailed validation messages.
- Connection Errors (Network issues, authentication failures)
Handled by SDK utilities with clear error messages for troubleshooting.
- Extraction Errors (Permission issues, unsupported features)
Managed by db/ extractors with graceful degradation when possible.
- Integration Errors (Component version mismatches, API changes)
Detected by adapters with context about which integration failed.
Extension Points for New Features¶
The modular architecture provides clear extension points:
- New Database Types
Add new subdirectories in both SDK utilities and db/ modules following existing patterns.
- New Data Sources (Beyond databases)
Create new top-level modules parallel to existing database modules.
- New Output Formats
Add new encoder functions in the db/ module’s second layer.
- New MCP Tools
Add new adapter functions that combine existing components in new ways.
- New Configuration Options
Extend the configuration hierarchy while maintaining backward compatibility.
Best Practices for System Modifications¶
- 1. Follow the Separation of Concerns
Each component should handle only its designated responsibility. Don’t add database-specific logic to adapters or MCP-specific logic to the db/ module.
- 2. Maintain Component Independence
Components should communicate through well-defined interfaces. Avoid tight coupling between database-specific modules.
- 3. Test Integration Points
When modifying any component, test its integration with adjacent components using real databases.
- 4. Update Documentation
Changes to component interfaces or integration patterns should be reflected in the relevant Developer Guide sections.
- 5. Preserve Configuration Compatibility
Changes should maintain backward compatibility with existing configuration files when possible.
Conclusion¶
The mcp_ohmy_sql system achieves its flexibility and maintainability through careful separation of concerns and well-defined integration patterns. Each component can be developed, tested, and maintained independently while contributing to a cohesive whole.
When working on the system:
Use the data flow diagram to understand how your changes affect the request/response cycle
Follow the decision tree to identify which components need modification
Test integration points to ensure your changes don’t break component coordination
Maintain the architectural patterns that make the system predictable and extensible
This architecture enables the system to grow and adapt while maintaining reliability and ease of maintenance for future developers.
See also
Database Metadata Module - Core schema processing
Model-Encoder-Extractor - Three-layer architecture
Per-SDK Utilities - Database-specific operations
Configuration System - Hierarchical configuration
Adapters - Integration bridge
Real Database Testing Strategy - Comprehensive testing