Skip to content

Modified to be Langflow Compatible #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
110 changes: 48 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
[![smithery badge](https://smithery.ai/badge/mysql-mcp-server)](https://smithery.ai/server/mysql-mcp-server)
[![MseeP.ai Security Assessment Badge](https://mseep.net/mseep-audited.png)](https://mseep.ai/app/designcomputer-mysql-mcp-server)
# MySQL MCP Server
A Model Context Protocol (MCP) implementation that enables secure interaction with MySQL databases. This server component facilitates communication between AI applications (hosts/clients) and MySQL databases, making database exploration and analysis safer and more structured through a controlled interface.
A Model Context Protocol (MCP) implementation that enables secure interaction with MySQL databases running on python server. This server component facilitates communication between AI applications (hosts/clients) and MySQL databases, making database exploration and analysis safer and more structured through a controlled interface.

> **Note**: MySQL MCP Server is not designed to be used as a standalone server, but rather as a communication protocol implementation between AI applications and MySQL databases.
> **Note**: MySQL MCP Server is not designed to be used as a standalone server, but rather as a communication protocol implementation between AI applications and MySQL databases. This modified version of MySQL MCP Server is compatible with [Langflow](https://github.com/langflow-ai/langflow) MCPTools component via STDIO protocol.

## Features
- List available MySQL tables as resources
Expand All @@ -14,79 +14,65 @@ A Model Context Protocol (MCP) implementation that enables secure interaction wi
- Secure database access through environment variables
- Comprehensive logging

## Installation
## Installation
### Manual Installation

1. Open up Windows CMD, cd to desktop location.
```bash
cd desktop
```

2. Cloning the repo
```bash
git clone https://github.com/CHuiV123/mysql_mcp_server_LangflowCompatible.git
```

3. Get into the folder directory:
```bash
pip install mysql-mcp-server
cd mysql_mcp_server_LangflowCompatible
```

### Installing via Smithery
To install MySQL MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/mysql-mcp-server):
4. Install dependencies
```bash
npx -y @smithery/cli install mysql-mcp-server --client claude
pip install -r requirements.txt
```

## Configuration
Set the following environment variables:
5. set up environment variable as below, replace all the "<-CHANGE THIS" section:
```bash
MYSQL_HOST=localhost # Database host
MYSQL_PORT=3306 # Optional: Database port (defaults to 3306 if not specified)
MYSQL_USER=your_username
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=your_database
set MYSQL_HOST="YOUR_DATABASE_HOST" <-CHANGE THIS
set MYSQL_PORT=3306 <-CHANGE THIS IF YOUR DATABASE IS NOT RUNNING ON 3306
set MYSQL_USER="YOUR_USER_NAME" <-CHANGE THIS
set MYSQL_PASSWORD="YOUR_PASSWORD" <-CHANGE THIS
set MYSQL_DATABASE="yOUR_DATABASE_NAME" <-CHANGE THIS
```

## Usage
### With Claude Desktop
Add this to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"mysql": {
"command": "uv",
"args": [
"--directory",
"path/to/mysql_mcp_server",
"run",
"mysql_mcp_server"
],
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "your_username",
"MYSQL_PASSWORD": "your_password",
"MYSQL_DATABASE": "your_database"
}
}
}
}
6. Start the server:
```bash
uv --directory . run mysql_mcp_server
```

### With Visual Studio Code
Add this to your `mcp.json`:
```json
{
"servers": {
"mysql": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"mysql-mcp-server",
"mysql_mcp_server"
],
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "your_username",
"MYSQL_PASSWORD": "your_password",
"MYSQL_DATABASE": "your_database"
}
}
}
}
Upon successful server start up, you shall see "mysql_mcp_server - INFO - Starting MCP STDIO server..."

## Setting up in Langflow MCPTools
*** pre-requisite, at this point MySQL MCP server should be already up and running.

1. Go to Langflow setting, look for MCP server.
2. Click **Add MCP Server**
3. Select **STDIO**
4. Server name= **MySQL_MCP**
5. Command= **python**
6. Arguments= **your directory path of server.py**
7. Add environment variable
```
MYSQL_HOST= **YOUR_HOST**
MYSQL_PORT= **YOUR_PORT**
MYSQL_USER= **YOUR_USER_NAME**
MYSQL_PASSWORD= **YOUR_PASSWORD**
MYSQL_DATABASE= **YOUR_DATABASE_NAME**
```
Note: Will need to install uv for this to work
8. Click **Add server**
9. Restart Langflow


### Debugging with MCP Inspector
While MySQL MCP Server isn't intended to be run standalone or directly from the command line with Python, you can use the MCP Inspector to debug it.
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mcp>=1.0.0
mysql-connector-python>=9.1.0
PyMySQL
uv
50 changes: 11 additions & 39 deletions src/mysql_mcp_server/server.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# server.py (MCP STDIO-Compatible)
import asyncio
import logging
import os
Expand All @@ -6,43 +7,35 @@
from mcp.server import Server
from mcp.types import Resource, Tool, TextContent
from pydantic import AnyUrl
from mcp.server.stdio import stdio_server

# Configure logging
# Log to stderr to not interfere with STDIO stream
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
stream=sys.stderr
)
logger = logging.getLogger("mysql_mcp_server")

def get_db_config():
"""Get database configuration from environment variables."""
config = {
"host": os.getenv("MYSQL_HOST", "localhost"),
"port": int(os.getenv("MYSQL_PORT", "3306")),
"user": os.getenv("MYSQL_USER"),
"password": os.getenv("MYSQL_PASSWORD"),
"database": os.getenv("MYSQL_DATABASE"),
# Add charset and collation to avoid utf8mb4_0900_ai_ci issues with older MySQL versions
# These can be overridden via environment variables for specific MySQL versions
"charset": os.getenv("MYSQL_CHARSET", "utf8mb4"),
"collation": os.getenv("MYSQL_COLLATION", "utf8mb4_unicode_ci"),
# Disable autocommit for better transaction control
"autocommit": True,
# Set SQL mode for better compatibility - can be overridden
"sql_mode": os.getenv("MYSQL_SQL_MODE", "TRADITIONAL")
}

# Remove None values to let MySQL connector use defaults if not specified
config = {k: v for k, v in config.items() if v is not None}

if not all([config.get("user"), config.get("password"), config.get("database")]):
logger.error("Missing required database configuration. Please check environment variables:")
logger.error("MYSQL_USER, MYSQL_PASSWORD, and MYSQL_DATABASE are required")
logger.error("Missing required database configuration.")
raise ValueError("Missing required database configuration")

return config

# Initialize server
app = Server("mysql_mcp_server")

@app.list_resources()
Expand Down Expand Up @@ -171,32 +164,11 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
logger.error(f"Error executing SQL '{query}': {e}")
logger.error(f"Error code: {e.errno}, SQL state: {e.sqlstate}")
return [TextContent(type="text", text=f"Error executing query: {str(e)}")]

async def main():
"""Main entry point to run the MCP server."""
from mcp.server.stdio import stdio_server

# Add additional debug output
print("Starting MySQL MCP server with config:", file=sys.stderr)
config = get_db_config()
print(f"Host: {config['host']}", file=sys.stderr)
print(f"Port: {config['port']}", file=sys.stderr)
print(f"User: {config['user']}", file=sys.stderr)
print(f"Database: {config['database']}", file=sys.stderr)

logger.info("Starting MySQL MCP server...")
logger.info(f"Database config: {config['host']}/{config['database']} as {config['user']}")

async with stdio_server() as (read_stream, write_stream):
try:
await app.run(
read_stream,
write_stream,
app.create_initialization_options()
)
except Exception as e:
logger.error(f"Server error: {str(e)}", exc_info=True)
raise
logger.info("Starting MCP STDIO server...")
async with stdio_server() as (reader, writer):
await app.run(reader, writer, app.create_initialization_options())

if __name__ == "__main__":
asyncio.run(main())
asyncio.run(main())