This repository contains production-ready implementations of MCP servers and agents for database access, as described in the blog series.
database_server.py- Basic MCP server implementation (learning/development)secure_database_server.py- Production-hardened version with security featuresagent_app.py- LangGraph agent that uses the MCP serverDockerfile- Container configuration for production deploymentdocker-compose.yml- Complete local testing environmentinit_db.sql- Sample database schema and datarequirements.txt- Python dependencies
This starts both a test database and the MCP server:
# Start everything
docker-compose up -d
# Check logs
docker-compose logs -f mcp-server
# Stop everything
docker-compose downRequirements:
- Python 3.11+
- PostgreSQL running locally
# Install dependencies
pip install -r requirements.txt
# Set environment variables
export DB_HOST=localhost
export DB_PASSWORD=your_password
export DB_USER=readonly_user
export DB_NAME=production
# Run the server
python database_server.pyThe agent application demonstrates how to integrate MCP servers with LangGraph.
# Set your Anthropic API key
export ANTHROPIC_API_KEY=your_key_here
# Run in interactive mode
python agent_app.py
# Run demo queries
python agent_app.py demo
# Use Docker MCP server instead of local
export MCP_SERVER_MODE=docker
python agent_app.pyMCP Inspector lets you test your server without building a full agent:
# Install Inspector
npm install -g @modelcontextprotocol/inspector
# Test your server
mcp-inspector python database_server.pyThen open the web interface shown in the terminal.
Enable detailed tracing to debug agent behavior:
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=your_langsmith_key
export LANGCHAIN_PROJECT=mcp-database-agent
python agent_app.pyView traces at https://smith.langchain.com
docker build -t mcp-database-server .docker run -d \
--name mcp-database \
--memory=512m \
--cpus=1.0 \
--security-opt seccomp=default.json \
--cap-drop=ALL \
--read-only \
--tmpfs /tmp \
-e DB_HOST=your-db-host \
-e DB_PASSWORD=secure_password \
mcp-database-server# Check container health
docker inspect --format='{{.State.Health.Status}}' mcp-database
# View logs
docker logs -f mcp-database
# View audit logs (if volume mounted)
docker exec mcp-database cat /var/log/mcp/server.log- Never hardcode credentials - Use environment variables or secrets management
- Run as non-root - The Dockerfile creates and uses a non-root user
- Use read-only database users - Grant only SELECT permissions
- Enable rate limiting - The secure version implements this
- Audit logging - All tool calls are logged for security review
- Input validation - All queries are validated before execution
- Network restrictions - Limit container network access
- Resource limits - Set memory and CPU limits
- Regular updates - Keep dependencies current
Check that:
- PostgreSQL is running:
pg_isready -h localhost - Credentials are correct
- Network allows connection (firewall, Docker networks)
The secure server limits to 20 queries/minute. Wait or adjust MAX_CALLS_PER_MINUTE in code.
This is intentional security. Only SELECT statements are permitted. To modify data, add specific tools with proper validation.
Ensure:
- MCP server is running and accessible
- Environment variables are set correctly
- Server logs show successful initialization
@mcp.tool()
async def your_tool_name(param: str) -> dict:
"""
Clear description for the AI.
Args:
param: Description of the parameter
"""
# Your implementation
return {"result": "data"}@mcp.resource("custom://your-resource")
async def your_resource() -> str:
"""Description of what this resource provides."""
data = {"key": "value"}
return json.dumps(data, indent=2)MIT License - feel free to use and modify for your projects.
For questions or issues:
- Check the blog posts for detailed explanations
- Review the code comments
- Test with MCP Inspector to isolate issues
- Check Docker/PostgreSQL logs for error messages
Happy building! 🚀