Skip to content

SainadhAmul/MCP-Implementation-2

Repository files navigation

MCP Database Server - Complete Implementation

This repository contains production-ready implementations of MCP servers and agents for database access, as described in the blog series.

Files Overview

  • database_server.py - Basic MCP server implementation (learning/development)
  • secure_database_server.py - Production-hardened version with security features
  • agent_app.py - LangGraph agent that uses the MCP server
  • Dockerfile - Container configuration for production deployment
  • docker-compose.yml - Complete local testing environment
  • init_db.sql - Sample database schema and data
  • requirements.txt - Python dependencies

Quick Start

Option 1: Docker Compose (Easiest)

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 down

Option 2: Local Python

Requirements:

  • 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.py

Using the Agent

The 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.py

Testing with MCP Inspector

MCP 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.py

Then open the web interface shown in the terminal.

LangSmith Tracing

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.py

View traces at https://smith.langchain.com

Production Deployment

Build the Docker image

docker build -t mcp-database-server .

Run with security hardening

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

Health monitoring

# 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

Security Best Practices

  1. Never hardcode credentials - Use environment variables or secrets management
  2. Run as non-root - The Dockerfile creates and uses a non-root user
  3. Use read-only database users - Grant only SELECT permissions
  4. Enable rate limiting - The secure version implements this
  5. Audit logging - All tool calls are logged for security review
  6. Input validation - All queries are validated before execution
  7. Network restrictions - Limit container network access
  8. Resource limits - Set memory and CPU limits
  9. Regular updates - Keep dependencies current

Troubleshooting

"Connection refused" errors

Check that:

  • PostgreSQL is running: pg_isready -h localhost
  • Credentials are correct
  • Network allows connection (firewall, Docker networks)

"Rate limit exceeded"

The secure server limits to 20 queries/minute. Wait or adjust MAX_CALLS_PER_MINUTE in code.

"Only SELECT queries allowed"

This is intentional security. Only SELECT statements are permitted. To modify data, add specific tools with proper validation.

Agent not finding tools

Ensure:

  • MCP server is running and accessible
  • Environment variables are set correctly
  • Server logs show successful initialization

Extending the Server

Add a new tool

@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"}

Add a new resource

@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)

License

MIT License - feel free to use and modify for your projects.

Support

For questions or issues:

  1. Check the blog posts for detailed explanations
  2. Review the code comments
  3. Test with MCP Inspector to isolate issues
  4. Check Docker/PostgreSQL logs for error messages

Happy building! 🚀

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages