-
Notifications
You must be signed in to change notification settings - Fork 913
feat(dynamodb-mcp-server): Add MySQL integration to support DynamoDB Data Modeling and Migration planning #1277
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
base: main
Are you sure you want to change the base?
Changes from 2 commits
187cc24
37f04fd
2761b40
448a8f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,13 +2,16 @@ | |
|
||
The official MCP Server for interacting with AWS DynamoDB | ||
|
||
This comprehensive server provides both operational DynamoDB management and expert design guidance, featuring 30+ operational tools for managing DynamoDB tables, items, indexes, backups, and more, expert data modeling guidance. | ||
This comprehensive server provides both operational DynamoDB management and expert design guidance, featuring 30+ operational tools for managing DynamoDB tables, items, indexes, backups, and more, expert data modeling guidance and also MySQL query capabilities for database analysis and migration planning. | ||
|
||
## Available MCP Tools | ||
|
||
### Design & Modeling | ||
- `dynamodb_data_modeling` - Retrieves the complete DynamoDB Data Modeling Expert prompt | ||
|
||
### MySQL Integration | ||
- `mysql_run_query` - Run SQL queries against MySQL databases for analysis and migration planning | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we really need to expose a free-from SQL query tool to the LLM. Have we considered having a parameterized SQL query to read the performance schema if that's our only use case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels odd that the DynamoDB MCP server would expose a tool to run MySQL queries. Was there another option? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to be explicit that this currently uses Aurora/RDS only. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that's the only query (read the performance schema) we need to run. I think in the workflow I have seen, we need to do validation to check if users have enabled the performance schema, and also I think there are queries regarding getting the whole schema for a database. So there is a need for a tool that can run many such queries. The question is, is there a way to restrict the queries to only a few approved by us? Worth checking. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm working on calling the mysql_run_query method within our analysis tool to execute the required SQL instead of registering as a separate tool. This will avoid exposing the tool publicly or user runs random calls. |
||
|
||
### Table Operations | ||
- `create_table` - Creates a new DynamoDB table with optional secondary indexes | ||
- `delete_table` - Deletes a table and all of its items | ||
|
@@ -61,6 +64,22 @@ To use these tools, ensure you have proper AWS credentials configured with appro | |
|
||
All tools support an optional `region_name` parameter to specify which AWS region to operate in. If not provided, it will use the AWS_REGION environment variable or default to 'us-west-2'. | ||
|
||
## MySQL Integration | ||
|
||
The DynamoDB MCP server includes MySQL integration to run mysql queries within DynamoDB MCP server. When configured, it adds a `mysql_run_query` tool for database analysis and migration planning. | ||
|
||
### MySQL Environment Variables | ||
|
||
Add these environment variables to DynamoDB MCP Server configuration to enable MySQL integration: | ||
|
||
- `MYSQL_CLUSTER_ARN`: RDS / Aurora MySQL cluster ARN | ||
- `MYSQL_SECRET_ARN`: AWS Secrets Manager secret ARN with database credentials | ||
- `MYSQL_DATABASE`: Database name to connect to | ||
- `MYSQL_AWS_REGION`: AWS region for MySQL cluster (default: "us-west-2") | ||
- `MYSQL_READONLY`: optional (default: "true") | ||
|
||
**Note**: MySQL integration tool is available only when these variables are set. | ||
|
||
## Prerequisites | ||
|
||
1. Install `uv` from [Astral](https://docs.astral.sh/uv/getting-started/installation/) or the [GitHub README](https://github.com/astral-sh/uv#installation) | ||
|
@@ -86,7 +105,12 @@ Add the MCP to your favorite agentic tools. (e.g. for Amazon Q Developer CLI MCP | |
"DDB-MCP-READONLY": "true", | ||
"AWS_PROFILE": "default", | ||
"AWS_REGION": "us-west-2", | ||
"FASTMCP_LOG_LEVEL": "ERROR" | ||
"FASTMCP_LOG_LEVEL": "ERROR", | ||
"MYSQL_CLUSTER_ARN": "[your data]", | ||
"MYSQL_SECRET_ARN": "[your data]", | ||
"MYSQL_DATABASE": "[your data]", | ||
"MYSQL_AWS_REGION": "us-west-2", | ||
"MYSQL_READONLY": "true" | ||
Comment on lines
+108
to
+113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Explain There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, will explain that in readme |
||
}, | ||
"disabled": false, | ||
"autoApprove": [] | ||
|
@@ -116,7 +140,12 @@ For Windows users, the MCP server configuration format is slightly different: | |
"env": { | ||
"FASTMCP_LOG_LEVEL": "ERROR", | ||
"AWS_PROFILE": "your-aws-profile", | ||
"AWS_REGION": "us-east-1" | ||
"AWS_REGION": "us-east-1",, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whats the purpose of this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently, we have DynamoDB API's using this particular AWS_REGION variable, we will remove that and use DB specific variables. It will help in case use resources (such as DB's) running on different regions. |
||
"MYSQL_CLUSTER_ARN": "[your data]", | ||
"MYSQL_SECRET_ARN": "[your data]", | ||
"MYSQL_DATABASE": "[your data]", | ||
"MYSQL_AWS_REGION": "us-west-2", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be place holder |
||
"MYSQL_READONLY": "true" | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,14 +50,19 @@ | |
from mcp.server.fastmcp import FastMCP | ||
from pathlib import Path | ||
from pydantic import Field | ||
from typing import Any, Dict, List, Literal, Union | ||
from typing import Any, Dict, List, Literal, Union, Optional, Annotated | ||
|
||
from awslabs.mysql_mcp_server.server import DBConnectionSingleton, run_query as mysql_query | ||
|
||
|
||
# Define server instructions and dependencies | ||
SERVER_INSTRUCTIONS = """The official MCP Server for interacting with AWS DynamoDB | ||
|
||
This server provides comprehensive DynamoDB capabilities with over 30 operational tools for managing DynamoDB tables, | ||
items, indexes, backups, and more, plus expert data modeling guidance through DynamoDB data modeling expert prompt | ||
items, indexes, backups, and more, plus expert data modeling guidance through DynamoDB data modeling expert prompt. | ||
|
||
MySQL Integration: This server also includes MySQL query capabilities through the run_query tool, enabling database | ||
analysis and migration planning from MySQL to DynamoDB. | ||
Comment on lines
+65
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For Aurora/RDS |
||
|
||
IMPORTANT: DynamoDB Attribute Value Format | ||
----------------------------------------- | ||
|
@@ -942,6 +947,39 @@ async def list_imports( | |
} | ||
|
||
|
||
@app.tool() | ||
@handle_exceptions | ||
async def mysql_run_query( | ||
sql: Annotated[str, Field(description='The SQL query to run')], | ||
query_parameters: Annotated[ | ||
Optional[List[Dict[str, Any]]], Field(description='Parameters for the SQL query') | ||
] = None, | ||
) -> list[dict]: | ||
"""Run a SQL query against a MySQL database for analysis and migration planning.""" | ||
|
||
if all([os.getenv('MYSQL_CLUSTER_ARN'), os.getenv('MYSQL_SECRET_ARN'), os.getenv('MYSQL_DATABASE')]): | ||
|
||
cluster_arn = os.getenv('MYSQL_CLUSTER_ARN') | ||
secret_arn = os.getenv('MYSQL_SECRET_ARN') | ||
database = os.getenv('MYSQL_DATABASE') | ||
region = os.getenv('AWS_REGION', 'us-west-2') | ||
readonly = os.getenv('MYSQL_READONLY', 'true').lower() == 'true' | ||
|
||
try: | ||
DBConnectionSingleton.initialize(cluster_arn, secret_arn, database, region, readonly) | ||
except Exception as e: | ||
return [{'error': f'MySQL initialization failed: {str(e)}'}] | ||
else: | ||
return [{'error': 'MySQL configuration not properly configured or available'}] | ||
|
||
|
||
class DummyContext: | ||
async def error(self, message): pass | ||
|
||
try: | ||
return await mysql_query(sql, DummyContext(), None, query_parameters) | ||
except Exception as e: | ||
return [{'error': f'MySQL query failed: {str(e)}'}] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See my previous comment about error handling |
||
|
||
def main(): | ||
"""Main entry point for the MCP server application.""" | ||
app.run() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,8 @@ dependencies = [ | |
"pydantic==2.11.7", | ||
"typing-extensions==4.14.1", | ||
"strands-agents>=1.5.0", | ||
"dspy-ai>=2.6.27" | ||
"dspy-ai>=2.6.27", | ||
"awslabs-mysql-mcp-server>=1.0.5", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we be dependent on other MCP servers. When we need to extend support to other databases, or on-prem how do we handle that. Take a dependence on N number of MCP's doesn't seem like a viable approach. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now MySQL package is focused on Aurora MySQL, PR (1246) is yet to merge which will support both AWS and on-prem mysql. so this 1 package will eventually take care of entire MySQL databases. We will have to find / use similar packages for other databases. |
||
] | ||
license = {text = "Apache-2.0"} | ||
license-files = ["LICENSE", "NOTICE" ] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import os | ||
import pytest | ||
import pytest_asyncio | ||
from awslabs.dynamodb_mcp_server.server import mysql_run_query | ||
|
||
|
||
class TestMySQLIntegration: | ||
"""Test MySQL integration functionality.""" | ||
|
||
@pytest.mark.asyncio | ||
async def test_mysql_connection_and_query(self, monkeypatch): | ||
"""Test MySQL connection initialization and query execution.""" | ||
# Set environment variables using monkeypatch | ||
monkeypatch.setenv('MYSQL_CLUSTER_ARN', 'arn:aws:rds:us-west-2:123456789012:cluster:test-cluster') | ||
monkeypatch.setenv('MYSQL_SECRET_ARN', 'arn:aws:secretsmanager:us-west-2:123456789012:secret:test-secret') | ||
monkeypatch.setenv('MYSQL_DATABASE', 'test_database') | ||
monkeypatch.setenv('MYSQL_AWS_REGION', 'us-west-2') | ||
monkeypatch.setenv('MYSQL_READONLY', 'true') | ||
|
||
# Mock the MySQL functions using monkeypatch | ||
def mock_initialize(*args, **kwargs): | ||
return True | ||
|
||
async def mock_query(*args, **kwargs): | ||
return [{'id': 1, 'name': 'test'}] | ||
|
||
monkeypatch.setattr('awslabs.dynamodb_mcp_server.server.DBConnectionSingleton.initialize', mock_initialize) | ||
monkeypatch.setattr('awslabs.dynamodb_mcp_server.server.mysql_query', mock_query) | ||
|
||
result = await mysql_run_query("SELECT * FROM users") | ||
|
||
assert result == [{'id': 1, 'name': 'test'}] | ||
|
||
@pytest.mark.asyncio | ||
async def test_mysql_missing_config(self, monkeypatch): | ||
"""Test MySQL query when configuration is missing.""" | ||
# Clear MySQL env vars using monkeypatch | ||
monkeypatch.delenv('MYSQL_CLUSTER_ARN', raising=False) | ||
monkeypatch.delenv('MYSQL_SECRET_ARN', raising=False) | ||
monkeypatch.delenv('MYSQL_DATABASE', raising=False) | ||
|
||
result = await mysql_run_query("SELECT * FROM users") | ||
assert 'error' in result[0] | ||
assert 'MySQL configuration not properly configured' in result[0]['error'] |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we considered to add or change existing evals to include this new use case? Please also consider adding a comment to the CR to show an end-to-end trace where the tool is exercised within the modeling workflow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 showing end-to-end trace, also keep add a task to add this to current evals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, will include an end-to-end trace in the PR for better understanding of the workflow. Also, will plan for evals changes later once the actual MySQL data analysis tools are merged.