guyinwonder168/database-mcp-server
If you are the rightful owner of database-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The Database MCP Server is a production-ready Model Context Protocol provider for SQL databases, written in Go.
Database MCP Server
A production-ready Model Context Protocol (MCP) provider for SQL databases, written in Go by guyinwonder. Supports MySQL, MariaDB, PostgreSQL, and SQLite. Features robust connection pooling, secure AES-GCM credential storage, structured JSON logging, comprehensive schema introspection, and a full suite of 12 MCP tools. Built and tested with Go 1.25.5.
🚀 Quick Start
# Clone the repository
git clone https://github.com/guyinwonder168/database-mcp-server.git
cd database-mcp-server
# Build the server
go build -o mcp-server ./cmd/server/main.go
# Run the server
./mcp-server
📋 Features
- 🔧 Interactive Setup - Auto-creates
config.yamlif missing; all configuration is managed via MCP actions - 👥 Profile Management - Add, update, and list database profiles via MCP
- ⚡ SQL Execution - Run arbitrary SQL queries (with read-only enforcement)
- 🔍 Schema Introspection - List tables/views, describe table schemas, list databases, and discover joins
- 📊 Sample Data Fetching - Fetch sample rows to infer data formats and value ranges
- 🔗 Automated Join Discovery - Suggest JOIN SQL for building complex queries
- 🤖 Smart Query Builder - Generate SQL queries programmatically (integrated into analyze-schema AIQuerySuggestions)
- 🔒 Read-only Profiles - Prevent write operations on selected profiles
- 🔐 Secure Credentials - Passwords are encrypted at rest using AES-GCM (256-bit)
- 🏊 Connection Pooling - Efficient, configurable pooling with max pool size
- 📝 Structured Logging & Error Handling - All actions and errors are logged as structured JSON; actionable error responses
- 🛠️ Tool Discovery -
list-toolsMCP action returns a machine-readable list of all available tools/actions - 🔌 Official MCP Protocol - Communication via stdio (not HTTP server; JSON is exchanged over stdio via official Go MCP SDK)
🛠️ Supported MCP Tools
| Tool | Description |
|---|---|
configure-profile | Create or update database connection profiles |
list-profiles | List all configured database profiles |
execute-sql | Execute arbitrary SQL queries with read-only enforcement |
list-tables | List tables in selected database |
describe-table | Describe comprehensive table schema with metadata |
list-databases | List accessible databases for profile |
mcp-info | Show provider version and author |
smart-query-builder | Generate SQL from high-level intent |
discover-joins | Discover foreign key relationships and suggest JOINs |
sample-data | Fetch sample rows to infer data formats |
list-tools | List all available MCP tools and descriptions |
analyze-schema | Comprehensive schema analysis with AI query suggestions |
📖 Documentation
Core Documentation
- 📋 - Detailed API specifications and examples
- 📊 - Current implementation tracking
- 🏗️ - Architecture and design details
- 📝 - Product requirements analysis with AI perspective
- 🔍 - Database-specific queries
- 🧪 - Test schema documentation
- 🗺️ - Strategic development planning
Memory Bank Documentation
The project includes a comprehensive memory bank system for AI assistants, located in .kilocode/rules/memory-bank/:
- 🏗️ - System architecture and component relationships
- 📋 - Project overview and requirements
- 📊 - Current state and recent changes
- 🎯 - Problem statement and solution overview
- 💻 - Technology stack and development setup
Project Planning
- 🗺️ - Comprehensive implementation strategy
- 📊 - Phase-by-phase development breakdown
- 🔍 - Technical compatibility analysis
- 📝 - Detailed task tracking
- 🐛 - Critical bug fix documentation
Version History
- 📋 - Detailed release notes and version history
🤝 Contributing
We welcome contributions! Please see our for development setup and workflow.
📄 License
This project is licensed under the .
🔐 Security
For security policies and vulnerability reporting, please see our .
📜 Code of Conduct
Please read our for community guidelines.
🧪 Testing
go test ./...
📊 Project Status
- Version: v1.0.1
- Author: guyinwonder
- Status: Production Ready ✅
- All 12 MCP tools are fully implemented and OpenAPI-aligned
- Enhanced schema introspection and sample data features
- AES-GCM encryption, connection pooling, and structured error handling
- Comprehensive unit and integration tests included
Recent Enhancements (v1.0.1)
- 🧠 Memory Bank System - Added comprehensive AI assistant memory bank for project context preservation
- 📚 Documentation Suite - Complete documentation overhaul with API specs, implementation status, and technical specifications
- 📋 Project Planning - Detailed roadmap and implementation tracking documents
- 🧪 Enhanced Testing - Added integration tests and MCP tool discovery regression tests
- 📝 Improved Logging - Better credential redaction and structured error handling
- 🔌 MCP Resources - Added
tools://listandprofile://{profile}resources for read-only inspection - 🌐 SSE Transport - Optional HTTP/SSE transport support for additional client compatibility
- 🔧 Git Configuration - Improved .gitignore to exclude logs and build artifacts
🤝 Enhancement Planning
Current Development Status: The Database MCP Server is production-ready with a comprehensive enhancement roadmap in progress.
Implementation Phases
- Phase 1 (Next 60 Days): Query optimization, validation, and enhanced NLP
- Phase 2 (60-90 Days): Data lineage and business intelligence
- Phase 3 (90+ Days): Schema evolution, advanced profiling, and multi-database federation
⭐ Star this repository if you find it useful!
Made with ❤️ by guyinwonder
Features
- Interactive Setup: Auto-creates
config.yamlif missing; all configuration is managed via MCP actions. - Profile Management: Add, update, and list database profiles via MCP.
- SQL Execution: Run arbitrary SQL queries (with read-only enforcement).
- Schema Introspection: List tables/views, describe table schemas, list databases, and discover joins.
- Sample Data Fetching: Fetch sample rows to infer data formats and value ranges.
- Automated Join Discovery: Suggest JOIN SQL for building complex queries.
- Smart Query Builder: Generate SQL queries programmatically (integrated into analyze-schema AIQuerySuggestions).
- Read-only Profiles: Prevent write operations on selected profiles.
- Secure Credentials: Passwords are encrypted at rest using AES-GCM (256-bit).
- Connection Pooling: Efficient, configurable pooling with max pool size.
- Structured Logging & Error Handling: All actions and errors are logged as structured JSON; actionable error responses.
- Tool Discovery:
list-toolsMCP action returns a machine-readable list of all available tools/actions. - Official MCP Protocol: Communication via stdio (not HTTP server; JSON is exchanged over stdio via the official Go MCP SDK).
Supported MCP Tools
configure-profilelist-profilesexecute-sqllist-tablesdescribe-tablelist-databasesmcp-infosmart-query-builderdiscover-joinssample-datalist-toolsanalyze-schema(provides AIQuerySuggestions integrated with Smart Query Builder)
Quick Start
-
Set up encryption key (required for password encryption):
- On first run,
config.yamlis auto-created with a secure random 32-characteraes_key. - To customize, edit
config.yamland setaes_keyto your own secure, random 32-character string.
- On first run,
-
Build and run the server:
go build -o mcp-server ./cmd/server/main.go ./mcp-server -
Add database profiles:
- Use the
configure-profileMCP tool (see examples below).
- Use the
-
Invoke MCP actions:
- Use any MCP-compatible client (e.g., Kilocode AI) to interact with the server.
Step-by-Step: Invoking MCP Actions
A. Using Kilocode AI
- Open Kilocode AI and ensure the Database MCP Server is running.
- In Kilocode AI, open the MCP Tools panel.
- Select the "database-mcp" provider from the list.
- Choose a tool (e.g.,
execute-sql,list-tables,configure-profile). - Fill in the required parameters (such as
profile_name,sql, etc.). - Click "Run" or "Execute" to send the action to the MCP server.
- View the results directly in the Kilocode AI interface.
B. Using JSON-RPC via Stdio (Script Example)
The Database MCP Server communicates over stdio (process input/output), not HTTP. To invoke actions programmatically, use a script that launches the server and communicates via stdin/stdout.
Example (Python):
import subprocess
import json
# Start the MCP server process
proc = subprocess.Popen(
['./mcp-server'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Prepare a JSON-RPC request (e.g., list-profiles)
request = json.dumps({
"method": "list-profiles",
"params": {}
}) + '\n'
# Send request and read response
proc.stdin.write(request)
proc.stdin.flush()
response = proc.stdout.readline()
print("Response:", response)
- Replace
./mcp-serverwith the path to your built binary if needed. - You can send any MCP action in this way; parameter and response schemas are documented below and in .
The server will respond with a JSON object containing the results.
C. Best Practices
- Always verify the MCP server is running before sending actions.
- Use the
list-toolsaction to discover available tools and their parameters. - Refer to for detailed schemas and examples.
Development (Go 1.25.5)
- Run all tests:
go test ./... - MCP tool discovery regression note: The project uses
github.com/modelcontextprotocol/go-sdk v1.1.0, which fixes the earliertools/listrejection during session initialization (v0.2.0 regression). The guard testinternal/mcp/tools_list_integration_test.goensures all registered tools are returned byListTools; downgrades will fail this test. - Optional live DB integration tests: set env vars and run
go test ./internal/mcp -run TestLive -count=1- Postgres:
DB_MCP_IT_PG_HOST,DB_MCP_IT_PG_PORT,DB_MCP_IT_PG_USER,DB_MCP_IT_PG_PASS,DB_MCP_IT_PG_DB,DB_MCP_IT_PG_SSLMODE(e.g., disable for local containers) - MySQL/MariaDB:
DB_MCP_IT_MYSQL_HOST,DB_MCP_IT_MYSQL_PORT,DB_MCP_IT_MYSQL_USER,DB_MCP_IT_MYSQL_PASS,DB_MCP_IT_MYSQL_DB
- Postgres:
- Logging to stdout is disabled by default to avoid corrupting MCP stdio. To mirror logs to stdout, set
MCP_LOG_TO_STDOUT=truewhen starting the server. - Optional HTTP/SSE transport: set
MCP_SSE_ADDR(e.g.,:8080) to expose the MCP server over SSE in addition to stdio. Example:MCP_SSE_ADDR=":8080" ./mcp-server- Claude Desktop: add an MCP provider pointing to
http://localhost:8080with transportsse(Claude auto-detects SSE when endpoint responds with SSE). - Codex CLI: set
MCP_SSE_ADDRas above and add/update the provider entry to point at the HTTP endpoint if Codex supports SSE; otherwise keep stdio (default). - Kilocode: prefers stdio; leave
MCP_SSE_ADDRunset unless testing SSE—Kilocode auto-uses the process command.
- Claude Desktop: add an MCP provider pointing to
Troubleshooting & Recovery
-
Invalid credentials
- Symptoms: MCP calls such as
execute-sqlorlist-databasesreturn a structured error whosemessageincludes the driver detail (e.g., MySQL “access denied for user”, Postgres “password authentication failed”). - Fix: inspect the profile via
list-profilesorprofile://{profile_name}resource; rerunconfigure-profilewith the corrected username/password/sslmode. For CI or local containers, ensureDB_MCP_IT_*env vars match the running DB. - Example structured error payload (MySQL bad password):
{ "status": "error", "error_code": "CONNECTION_FAILED", "message": "Database connection failed", "details": "Access denied for user 'root'@'127.0.0.1' (using password: YES)", "suggestions": [ {"action": "Check database server", "description": "Verify the database server is running and accessible"}, {"action": "Verify connection details", "description": "Check host, port, username, and password in the profile configuration"}, {"action": "Check network connectivity", "description": "Ensure there are no firewall or network issues blocking the connection"} ], "context": { "profile_name": "mysql_live", "db_type": "mysql", "operation": "connect", "database": "project" } }
- Symptoms: MCP calls such as
-
Network drop / host unreachable
- Symptoms: errors like “connection refused”, “EOF”, or “context deadline exceeded” when the DB container is stopped, the port is blocked, or DNS/host is wrong.
- Fix: confirm the DB process is up and listening (e.g.,
podman ps,nc -z host port), then rerun the MCP action; the server will open a fresh connection on each request. SetMCP_LOG_TO_STDOUT=trueto surface the original driver error while debugging. - Example structured error payload (Postgres host down):
{ "status": "error", "error_code": "CONNECTION_FAILED", "message": "Database connection failed", "details": "dial tcp 127.0.0.1:54320: connect: connection refused", "suggestions": [ {"action": "Check database server", "description": "Verify the database server is running and accessible"}, {"action": "Verify connection details", "description": "Check host, port, username, and password in the profile configuration"}, {"action": "Check network connectivity", "description": "Ensure there are no firewall or network issues blocking the connection"} ], "context": { "profile_name": "pg_live", "db_type": "postgres", "operation": "connect", "database": "project" } }
-
Read-only enforcement
- Symptoms: any write (
INSERT/UPDATE/DELETE/DDL) on a profile withreadonly: truereturns the MCP error “profile is read-only” before the statement is sent to the database. - Fix: perform writes via a non-readonly profile or flip
readonly: falseusingconfigure-profile; verify withlist-profilesorprofile://{profile_name}. The guard path is covered byTestHandleExecuteSQL_ParamAndReadonly. - Example structured error payload (INSERT on readonly profile):
{ "status": "error", "error_code": "SQL_EXECUTION_ERROR", "message": "Read-only profile restriction", "details": "Detected disallowed verb 'insert' in query for readonly profile", "suggestions": [ {"action": "Use read-only queries", "description": "Only single SELECT/SHOW/DESCRIBE/EXPLAIN/PRAGMA queries are allowed", "example": "SELECT * FROM users LIMIT 50"}, {"action": "Use a different profile", "description": "Switch to a profile that allows write operations"} ], "context": { "profile_name": "readonly_profile", "query": "INSERT INTO users(name) VALUES('alice')" } }
- Symptoms: any write (
MCP Resources
The server now exposes MCP resources (in addition to tools):
tools://list— JSON array of all registered tools and descriptions.profile://{profile_name}— JSON metadata for a profile with secrets redacted.
Access these via your MCP client’s Resources panel (Codex/Kilocode). Tools remain the primary interaction surface; resources provide quick, read-only inspection.
Release & Packaging
- Build release binary:
go build -o mcp-server ./cmd/server - Smoke run (stdout logging enabled):
MCP_LOG_TO_STDOUT=true ./mcp-server - Live DB smoke tests (podman/local):
DB_MCP_IT_PG_HOST=127.0.0.1 DB_MCP_IT_PG_PORT=54320 DB_MCP_IT_PG_USER=root DB_MCP_IT_PG_PASS=12345678 DB_MCP_IT_PG_DB=project DB_MCP_IT_MYSQL_HOST=127.0.0.1 DB_MCP_IT_MYSQL_PORT=33006 DB_MCP_IT_MYSQL_USER=root DB_MCP_IT_MYSQL_PASS='#12345678' DB_MCP_IT_MYSQL_DB=project go test ./internal/mcp -run Live -count=1 - Update changelog (
CHANGELOG.md) for the new version before tagging. - Suggested tag for this release:
v1.0.1(fixes MCP tool detection, adds structured error payload examples, and verifies live MySQL/Postgres connectivity).
Comprehensive Configuration Examples
config.yaml Structure
max_pool_size: 10
aes_key: "<your-32-char-aes-key>"
profiles:
- profile_name: "mariadb-profile"
db_type: "mariadb"
host: "localhost"
port: 3306
username: "mariauser"
password: "<encrypted>"
database_name: "mydb"
readonly: false
- profile_name: "mysql-profile"
db_type: "mysql"
host: "localhost"
port: 3306
username: "mysqluser"
password: "<encrypted>"
database_name: "mydb"
readonly: true
- profile_name: "postgres-profile"
db_type: "postgres"
host: "localhost"
port: 5432
username: "pguser"
password: "<encrypted>"
database_name: "mydb"
sslmode: "require" # Set to verify-full in production with proper certificates
readonly: false
- profile_name: "sqlite-profile"
db_type: "sqlite"
database_name: "./data/mydb.sqlite"
readonly: true
MariaDB Example
- profile_name: "mariadb-prod"
db_type: "mariadb"
host: "db.example.com"
port: 3306
username: "admin"
password: "<encrypted>"
database_name: "production"
readonly: false
MySQL Example
- profile_name: "mysql-dev"
db_type: "mysql"
host: "localhost"
port: 3306
username: "devuser"
password: "<encrypted>"
database_name: "devdb"
readonly: true
PostgreSQL Example
- profile_name: "pg-main"
db_type: "postgres"
host: "localhost"
port: 5432
username: "pguser"
password: "<encrypted>"
database_name: "main"
sslmode: "require" # Options: disable | require | verify-ca | verify-full (recommended: verify-full in production)
readonly: false
SQLite Example
- profile_name: "sqlite-local"
db_type: "sqlite"
database_file: "./data/local.sqlite"
readonly: true
Notes:
passwordfields must be encrypted using the server's AES key (handled automatically by MCP actions).- For SQLite, only
database_name(file path or :memory:) andreadonlyare required.
Usage Examples
configure-profile
Create or update a database connection profile.
Parameters:
- profile_name (string, required)
- db_type (string, required): "mysql" | "mariadb" | "postgres" | "sqlite"
- host (string, optional; required for non-sqlite)
- port (number, optional; required for non-sqlite)
- username (string, optional; required for non-sqlite)
- password (string, optional; required for non-sqlite)
- database_name (string, required; for sqlite this is a file path like ./data.db or :memory:)
- readonly (boolean, required)
- sslmode (string, optional; Postgres only: disable | require | verify-ca | verify-full; defaults to require; use verify-full in production with proper CA/cert validation)
Request example:
{
"method": "configure-profile",
"params": {
"profile_name": "pg-main",
"db_type": "postgres",
"host": "localhost",
"port": 5432,
"username": "pguser",
"password": "mypassword",
"database_name": "main",
"readonly": false
}
}
Success response:
Profile configured successfully.
Error response: Structured JSON with error_code and suggestions (see Error Handling section).
execute-sql
Execute an arbitrary SQL query or statement.
Parameters:
- profile_name (string, required)
- database_name (string, required)
- sql (string, required)
- params (array, optional): positional parameters for prepared queries (use ? placeholders)
Readonly enforcement:
- When the selected profile is readonly, only SELECT, SHOW, DESCRIBE, EXPLAIN, PRAGMA are allowed. Others are blocked with a structured error.
Database context:
- MySQL/MariaDB: issues USE database_name when the provided database differs from the profile default.
- Postgres/SQLite: DSN is built for the provided database.
Request example (query with params):
{
"method": "execute-sql",
"params": {
"profile_name": "pg-main",
"database_name": "main",
"sql": "SELECT id, name, age FROM users WHERE age > ? LIMIT 10",
"params": [21]
}
}
Success response (query):
{
"columns": ["id", "name", "age"],
"rows": [
[1, "Alice", 25],
[2, "Bob", 32]
]
}
Success response (non-query):
{
"affected": 3
}
Error response: Structured JSON with error_code and suggestions.
analyze-schema
{
"method": "analyze-schema",
"params": {
"profile_name": "pg-main",
"database_name": "main",
"analysis_level": "detailed",
"include_tables": ["users", "orders"],
"sample_size": 10,
"include_queries": true
}
}
Notes:
- analysis_level: "basic" | "detailed" | "comprehensive"
- include_tables/exclude_tables: filter scope of analysis
- include_queries: when true, response includes AIQuerySuggestions powered by Smart Query Builder
Response (abridged):
{
"analysis_metadata": {
"analysis_level": "detailed",
"database_type": "postgres",
"analysis_timestamp": "2025-08-06T10:00:00Z"
},
"database_overview": {
"total_tables": 2,
"total_columns": 7
},
"table_schemas": {
"users": {
"column_count": 2,
"key_columns": {
"primary_key": "id",
"foreign_keys": []
},
"columns": [
{"column_name": "id", "data_type": "INT", "is_nullable": false, "is_primary_key": true},
{"column_name": "name", "data_type": "VARCHAR(255)", "is_nullable": false}
]
},
"orders": {
"column_count": 3,
"key_columns": {
"primary_key": "order_id",
"foreign_keys": ["user_id"]
},
"columns": [
{"column_name": "order_id", "data_type": "INT", "is_nullable": false, "is_primary_key": true},
{"column_name": "user_id", "data_type": "INT", "is_nullable": false, "is_foreign_key": true, "foreign_key_ref": {"ref_table": "users", "ref_column": "id"}},
{"column_name": "total", "data_type": "DECIMAL(10,2)", "is_nullable": false}
]
}
},
"relationship_graph": {
"foreign_keys": [
{
"from_table": "orders",
"from_column": "user_id",
"to_table": "users",
"to_column": "id",
"relationship_type": "many_to_one",
"suggested_join": "JOIN users u ON orders.user_id = u.id"
}
]
},
"ai_query_suggestions": {
"data_exploration": [
{
"question": "Top 10 recent orders with customer name",
"sql": "SELECT o.order_id, u.name, o.total FROM orders o JOIN users u ON o.user_id = u.id ORDER BY o.order_id DESC LIMIT 10"
}
],
"business_intelligence": [
{
"question": "Monthly revenue trend",
"sql": "SELECT date_trunc('month', created_at) AS month, SUM(total) AS revenue FROM orders GROUP BY 1 ORDER BY 1"
}
]
}
}
### list-profiles
List configured profiles.
Request:
```json
{
"method": "list-profiles",
"params": {}
}
Response:
{
"profiles": [
{ "profile_name": "pg-main", "db_type": "postgres" },
{ "profile_name": "sqlite-local", "db_type": "sqlite" }
]
}
list-tables
List tables in a database/schema.
Parameters:
- profile_name (string, required)
- database_name (string, required)
Request:
{
"method": "list-tables",
"params": {
"profile_name": "pg-main",
"database_name": "main"
}
}
Response:
{
"tables": ["users", "orders", "products"]
}
describe-table
Describe table columns and metadata.
Parameters:
- profile_name (string, required)
- database_name (string, required)
- table_name (string, required)
Request:
{
"method": "describe-table",
"params": {
"profile_name": "pg-main",
"database_name": "main",
"table_name": "users"
}
}
Response (example shape):
{
"columns": [
{
"name": "id",
"type": "integer",
"nullable": false,
"key": "PRI",
"default": null,
"comment": "",
"extra": "",
"character_set": "",
"collation": "",
"auto_increment": true,
"max_length": null,
"precision": 32,
"scale": 0
}
]
}
list-databases
List databases accessible to the profile.
Parameters:
- profile_name (string, required)
Request:
{
"method": "list-databases",
"params": {
"profile_name": "pg-main"
}
}
Response:
{
"databases": ["main", "analytics", "test"]
}
Note: For sqlite, the response will include only the configured database_name.
sample-data
Fetch sample rows from a table.
Parameters:
- profile_name (string, required)
- database_name (string, required)
- table_name (string, required)
- sample_size (number, optional; default 3; max 100)
Request:
{
"method": "sample-data",
"params": {
"profile_name": "mysql-dev",
"database_name": "devdb",
"table_name": "orders",
"sample_size": 5
}
}
Response:
{
"table_name": "orders",
"sample_size": 5,
"columns": ["id", "user_id", "total"],
"sample_rows": [
[1, 10, "99.50"],
[2, 11, "150.00"]
],
"summary": "Retrieved 2 sample row(s) from table 'orders' with 3 column(s)."
}
discover-joins
Discover foreign key relationships and suggest JOIN SQL.
Parameters:
- profile_name (string, required)
- tables (array of string, optional): restrict discovery to these tables
Request:
{
"method": "discover-joins",
"params": {
"profile_name": "analytics_db",
"tables": ["orders", "customers"]
}
}
Response:
{
"joins": [
{
"from_table": "orders",
"from_column": "customer_id",
"to_table": "customers",
"to_column": "id",
"relationship": "foreign_key",
"suggested_join_sql": "SELECT * FROM orders JOIN customers ON orders.customer_id = customers.id"
}
],
"summary": "Discovered 1 join(s) based on foreign key relationships."
}
smart-query-builder
Generate SQL from high-level intent and optional table hints.
Parameters:
- profile_name (string, required)
- intent (string, required)
- database_name (string, optional)
- table_names (array of string, optional)
Request:
{
"method": "smart-query-builder",
"params": {
"profile_name": "pg-main",
"intent": "attendance dashboard",
"database_name": "main",
"table_names": ["attendance"]
}
}
Response:
{
"sql": "SELECT id, employee_id, status FROM attendance;",
"explanation": "Selected table 'attendance' and columns [id, employee_id, status] based on keywords from intent 'attendance dashboard'."
}
mcp-info
Show provider version and author.
Request:
{
"method": "mcp-info",
"params": {}
}
Response (text):
Database MCP Provider
Author: guyinwonder
Version: v1.0.0
Created using OpenAI GPT-4.1 via VSCode Kilocode AI code assistant extension.
list-tools
List all available tools and descriptions.
Request:
{
"method": "list-tools",
"params": {}
}
Response:
{
"tools": [
{ "name": "configure-profile", "description": "Create or update a database connection profile. Required for all database actions.\nExample:\n{\"profile_name\":\"some-profile-name\",\"db_type\":\"mariadb\",\"host\":\"localhost\",\"port\":3306,\"username\":\"app\",\"password\":\"secret\",\"database_name\":\"mysql\",\"readonly\":false}" },
{ "name": "list-profiles", "description": "List all configured database profiles.\nExample:\n{}" },
{ "name": "execute-sql", "description": "Execute an arbitrary SQL query or statement. Use the 'database_name' parameter to select a database if needed.\nNote: For cross-database queries or describing tables in another database, use fully qualified table names (e.g., db.table).\nExample:\n{\"profile_name\":\"some-profile-name\",\"database_name\":\"some-database-name\",\"sql\":\"SELECT * FROM some-table-name WHERE some-field-name=34;\"}\n{\"profile_name\":\"some-profile-name\",\"sql\":\"DESCRIBE some-database-name.some-table-name\"}" },
{ "name": "list-tables", "description": "List all tables in the selected database. Use 'database_name' to override the profile's default database.\nExample:\n{\"profile_name\":\"some-profile-name\",\"database_name\":\"some-database-name\"}" },
{ "name": "describe-table", "description": "Describe the comprehensive schema of a table including columns, types, constraints, comments, and metadata. Returns detailed information to enable AI/agents to understand table structure and build intelligent queries.\nReturns: column names, data types, nullable status, key constraints, default values, column comments, character sets, collation, auto-increment status, max length, precision, and scale.\nExample:\n{\"profile_name\":\"some-profile-name\",\"database_name\":\"some-database-name\",\"table_name\":\"some-table-name\"}" },
{ "name": "list-databases", "description": "List all databases/schemas available to the profile.\nExample:\n{\"profile_name\":\"some-profile-name\"}" },
{ "name": "analyze-schema", "description": "Perform schema analysis for a database, including table/column metadata, relationships, and sample data integration.\n\nRequired parameters:\n\t - profile_name: Database profile to analyze\n\t - analysis_level: REQUIRED. Must be one of \"basic\", \"detailed\", \"comprehensive\".\n\t - BASIC: Quick overview for initial exploration\n\t - DETAILED: Comprehensive schema for query construction\n\t - COMPREHENSIVE: Deep business context with AI insights\n\nOptional parameters:\n\t - database_name: Specific database (uses profile default if empty)\n\t - include_tables: Specific tables to analyze (all if empty)\n\t - exclude_tables: Tables to exclude from analysis\n\t - sample_size: Rows to sample per table (default: 10)\n\t - include_queries: Generate query suggestions (default: true)\n\nAI agents MUST specify analysis_level. Example:\n{\"profile_name\":\"analytics_db\",\"analysis_level\":\"detailed\",\"database_name\":\"analytics_db\"}" },
{ "name": "mcp-info", "description": "Show MCP provider version and author.\nExample:\n{}" },
{ "name": "smart-query-builder", "description": "Generate optimized SQL from high-level intent and schema analysis.\nInput: profile_name, intent (natural language), optional database_name/table_name(s).\nReturns: generated SQL, explanation, and any errors.\nExample:\n{\"profile_name\":\"some-profile-name\",\"intent\":\"attendance dashboard\"}" },
{ "name": "discover-joins", "description": "Discover joinable relationships (foreign keys) between tables and suggest JOIN SQL.\nInput: profile_name (required), tables (optional).\nReturns: list of join suggestions and summary.\nExample:\n{\"profile_name\":\"analytics_db\",\"tables\":[\"orders\",\"customers\"]}" },
{ "name": "sample-data", "description": "Fetch sample rows from a table to help AI/agents infer data types, formats, and value ranges.\nInput: profile_name (required), table_name (required), database_name (optional), sample_size (optional, default: 3).\nReturns: sample rows with column names and values.\nExample:\n{\"profile_name\":\"analytics_db\",\"table_name\":\"users\",\"sample_size\":5}" },
{ "name": "list-tools", "description": "List all available MCP tools and their descriptions.\nExample:\n{}" }
]
}
Listing Tools
{
"method": "list-tools"
}
Installation & Setup
Prerequisites
- Go 1.23+ installed (
go version) - Supported databases: MySQL, MariaDB, PostgreSQL, SQLite
Build & Run
git clone <repo-url>
cd database-mcp-provider
go mod download
go build -o mcp-server ./cmd/server/main.go
./mcp-server
- The server runs as a stdio-based MCP provider (no HTTP server or port).
- On first run, if
config.yamlis missing, a minimal config with a secure random AES key is auto-created. - All configuration is managed via MCP actions (no interactive CLI prompts).
- To add database profiles, use the
configure-profileMCP action.
Best Practices
- Use strong, random
aes_keyfor encryption. - Set
readonly: truefor profiles used by AI/agents to prevent accidental writes. - Monitor
mcp-provider.logfor errors and audit events. - Use connection pooling (
max_pool_size) appropriate for your workload. - Never store plaintext passwords; always use MCP actions to manage credentials.
- Regularly update dependencies and run tests (
go test ./...).
Security
- Passwords are encrypted at rest with AES-GCM (256-bit) using a 32-character key (auto-generated if absent).
- Logger now performs automatic credential redaction (passwords, tokens, keys, DSN inline secrets) to prevent accidental leakage in logs.
- No plaintext credentials are stored or logged; only redacted placeholders (REDACTED) appear for sensitive fields.
- All operations use structured JSON logging for auditability; error analysis produces actionable suggestions.
- Read-only profiles enforce access control (write / DDL / unsafe multi-statement queries blocked; WITH + SELECT allowed).
- PostgreSQL profiles default to
sslmode=require(encryption in transit). For production, use:sslmode=verify-full(recommended): validates certificate chain AND hostnamesslmode=verify-ca: validates CA chain only (use only when hostname match cannot be satisfied)- Avoid
disableexcept in isolated, disposable dev environments
- Certificate Guidance (PostgreSQL):
- Server certificate & key managed on the database host (standard PostgreSQL configuration).
- Client validation paths (lib/pq) typically honor environment variables:
SSLROOTCERT(root CA),SSLCERT(client cert),SSLKEY(client key)
- Alternatively place certificates in a secure directory (e.g.
/etc/db_certs/) with 600 permissions for private keys. - Rotate certificates periodically; monitor expiration with CI checks.
- Operational Hardening:
- Restrict filesystem permissions on
config.yaml(e.g.chmod 600). - Do not commit
config.yamlto version control; add to.gitignore. - Rotate AES key if compromise suspected (requires re-encrypting stored passwords via re-saving profiles).
- Prefer separate least-privilege database users for readonly vs write profiles.
- Restrict filesystem permissions on
- Threat Mitigations:
- SQL injection minimized by prepared statements path (
paramsusage). - Multi-statement execution blocked for readonly profiles.
- Excessive quality issue lists capped to reduce potential data leakage surface.
- SQL injection minimized by prepared statements path (
- Future (optional) Enhancements (not yet implemented):
- Support for explicit client cert/key fields in profile for managed rotation workflows.
- Pluggable secret manager integration (e.g., environment / vault) instead of storing AES key in config.
Kilocode AI Integration
This provider is fully compatible with Kilocode AI's MCP integration.
Example Kilocode AI config snippet:
mcp_providers:
- name: database-mcp
command: "/[path to ]/mcp-server"
workingDirectory: "/[path to ]"
args: []
disabled: false
alwaysAllow:
- "list-profiles"
commandis the full path to your built mcp-server binary.workingDirectoryis the path where the binary is located.
Documentation
Core Documentation
- All MCP actions and usage examples are documented in .
- The
list-toolsMCP action provides a machine-readable list of all available tools/actions. - No HTTP endpoints or web server are provided; all communication is via stdio MCP protocol.
Comprehensive Documentation Suite
- API Documentation: - Detailed API specifications and examples
- Implementation Status: - Current implementation tracking
- Technical Specifications: - Architecture and design details
- PRD Analysis: - Product requirements analysis with AI perspective
- Schema Introspection Queries: - Database-specific queries
- Test Enhanced Schema: - Test schema documentation
- Implementation Roadmap: - Strategic development planning
GitHub Project Documentation
- Contributing Guidelines: - Development setup and contribution workflow
- Code of Conduct: - Community guidelines and behavior standards
- Security Policy: - Security practices and vulnerability reporting
- Issue Templates: Bug reports and feature request templates in
- Pull Request Template: - Comprehensive PR checklist
- License: - MIT license for open source use
Memory Bank Documentation
The project includes a comprehensive memory bank system for AI assistants, located in .kilocode/rules/memory-bank/:
- Architecture: - System architecture and component relationships
- Brief: - Project overview and requirements
- Context: - Current state and recent changes
- Product: - Problem statement and solution overview
- Tech: - Technology stack and development setup
Project Planning
- Roadmap: - Comprehensive implementation strategy
- Vertical Slices: - Phase-by-phase development breakdown
- Architecture Validation: - Technical compatibility analysis
- Implementation Tasks: - Detailed task tracking
- MCP Tool Detection Fix: - Critical bug fix documentation
Version History
- CHANGELOG: - Detailed release notes and version history
Testing
go test ./...
Project Status
- Version: v1.0.1
- Author: guyinwonder
- All 12 MCP tools are fully implemented and OpenAPI-aligned.
- Enhanced schema introspection and sample data features.
- AES-GCM encryption, connection pooling, and structured error handling are enforced.
- Comprehensive unit and integration tests included.
- Ready for production use.
Recent Enhancements (v1.0.1)
- Memory Bank System: Added comprehensive AI assistant memory bank for project context preservation
- Documentation Suite: Complete documentation overhaul with API specs, implementation status, and technical specifications
- Project Planning: Detailed roadmap and implementation tracking documents
- Enhanced Testing: Added integration tests and MCP tool discovery regression tests
- Improved Logging: Better credential redaction and structured error handling
- MCP Resources: Added
tools://listandprofile://{profile}resources for read-only inspection - SSE Transport: Optional HTTP/SSE transport support for additional client compatibility
- Git Configuration: Improved .gitignore to exclude logs and build artifacts
License
MIT
Enhancement Planning
Current Development Status: The Database MCP Server is production-ready with a comprehensive enhancement roadmap in progress.
Implementation Phases:
- Phase 1 (Next 60 Days): Query optimization, validation, and enhanced NLP
- Phase 2 (60-90 Days): Data lineage and business intelligence
- Phase 3 (90+ Days): Schema evolution, advanced profiling, and multi-database federation
Planning Documents:
- - Strategic overview
- - Comprehensive implementation strategy
- - Detailed phase breakdowns
- - Technical compatibility analysis
Ready for immediate enhancement development while maintaining production stability.