Claude Code를 사용하다 보면 MCP(Model Context Protocol) 서버를 통해 다양한 외부 서비스와 연동할 수 있다. 그중에서도 MySQL 데이터베이스 연결은 개발 작업에 꽤 유용한데, 최근 AWS RDS MySQL에 연결하려다 꽤나 고생했던 경험을 공유하려고 한다.
문제 상황
어느 날 claude mcp list 명령어를 실행했더니 MySQL MCP 서버만 연결에 실패하고 있었다.
$ claude mcp list
context7: https://mcp.context7.com/mcp (HTTP) - ✓ Connected
sequential-thinking: npx @modelcontextprotocol/server-sequential-thinking - ✓ Connected
mysql: npx -y @benborgers/mysql-mcp - ✗ Failed to connect
...
다른 MCP 서버들은 잘 연결되는데 MySQL만 실패한다. 뭐가 문제일까?
원인 분석 과정
1단계: 패키지 존재 여부 확인
먼저 해당 패키지를 직접 실행해봤다.
$ npx -y @benborgers/mysql-mcp
npm error 404 Not Found - GET https://registry.npmjs.org/@benborgers%2fmysql-mcp - Not found
npm error 404 '@benborgers/mysql-mcp@*' is not in this registry.
패키지가 npm에서 삭제되어 있었다. 이런 경우가 종종 있는데, 패키지 관리자가 패키지를 unpublish하거나 이름을 변경하면 기존 설정이 깨지게 된다.
2단계: 대체 패키지 탐색
npm에서 MySQL MCP 관련 패키지들을 검색해봤다.
$ npm search mysql mcp
mysql-mcp - MySQL MCP server for executing SELECT queries
@benborla29/mcp-server-mysql - MySQL MCP Server optimized for Claude Code
@keevor/mysql-mcp-server - MySQL MCP Server for Cursor
...
여러 대체 패키지가 있었고, 그중 @benborla29/mcp-server-mysql이 Claude Code에 최적화되어 있다고 해서 이걸로 교체해봤다.
3단계: 여전히 연결 실패
패키지를 교체하고 환경 변수도 새 패키지 형식에 맞게 수정했다.
$ claude mcp add-json mysql '{
"type": "stdio",
"command": "npx",
"args": ["-y", "@benborla29/mcp-server-mysql"],
"env": {
"MYSQL_HOST": "xxx.rds.amazonaws.com",
"MYSQL_PORT": "3306",
"MYSQL_USER": "plab_readonly",
"MYSQL_PASS": "xxx",
"MYSQL_DB": "plab",
"MYSQL_SSL": "true"
}
}' -s user
그런데 여전히 연결 실패. 직접 실행해보니 이런 오류가 나왔다.
Access denied for user 'plab_readonly'@'124.50.8.175' (using password: YES)4단계: PyCharm에서는 된다?
이상한 점은 PyCharm DataGrip에서 동일한 자격 증명으로 연결이 잘 된다는 것이다. PyCharm의 연결 설정을 자세히 보니 SSL: yes로 표시되어 있었다.
PyCharm에서 연결 후 다음 쿼리를 실행해봤다.
SELECT USER(), CURRENT_USER(), @@hostname;
결과:
{
"user()": "plab_readonly@124.50.8.175",
"CURRENT_USER()": "plab_readonly@%"
}
같은 IP에서 연결이 성공했다! 이건 네트워크나 계정 권한 문제가 아니라 클라이언트 연결 방식의 차이라는 뜻이다.
5단계: SSL 연결 테스트
MySQL CLI로 SSL 연결을 테스트해봤다.
# SSL 없이 연결 시도 - 실패
$ mysql -h xxx.rds.amazonaws.com -u plab_readonly -p'xxx' plab
ERROR 1045 (28000): Access denied for user 'plab_readonly'@'124.50.8.175'
# AWS RDS CA 인증서를 다운로드
$ curl -s https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem -o /tmp/rds-ca-bundle.pem
# SSL + CA 인증서로 연결 시도 - 성공!
$ mysql --defaults-file=/tmp/mysql-test.cnf -e "SELECT 1 as test;"
+------+
| test |
+------+
| 1 |
+------+
SSL 연결이 필수였던 것이다. AWS RDS는 보안 정책에 따라 SSL 연결만 허용하도록 설정할 수 있는데, 이 DB가 그런 경우였다.
6단계: Node.js mysql2로 테스트
MCP 서버는 Node.js로 동작하니까, Node.js mysql2 패키지로도 테스트해봤다.
const mysql = require('mysql2/promise');
const connection = await mysql.createConnection({
host: 'xxx.rds.amazonaws.com',
user: 'plab_readonly',
password: 'xxx',
database: 'plab',
ssl: { rejectUnauthorized: false } // SSL 활성화
});
const [rows] = await connection.execute('SELECT 1 as test');
console.log('SUCCESS:', rows); // 성공!
Node.js에서도 SSL 옵션을 제대로 설정하면 연결이 된다.
7단계: 패키지 버그 발견
그렇다면 @benborla29/mcp-server-mysql 패키지는 왜 안 될까? 패키지 소스를 까봤다.
$ npm pack @benborla29/mcp-server-mysql
$ tar -xzf benborla29-mcp-server-mysql-*.tgz
$ grep "ssl" package/dist/index.js
ssl: process.env.MYSQL_SSL === "true" ? "enabled" : "disabled",
문제를 찾았다. 패키지가 ssl: "enabled"로 설정하고 있는데, 이건 mysql2의 유효한 SSL 옵션이 아니다!
mysql2에서 SSL을 활성화하려면 이렇게 해야 한다:
ssl: true
// 또는
ssl: { rejectUnauthorized: false }
ssl: "enabled"는 그냥 무시되어서 SSL 없이 연결을 시도하게 되고, 결국 인증 실패가 발생한 것이다.
해결 방법
기존 패키지들이 SSL을 제대로 지원하지 않아서, 직접 간단한 MCP 서버를 만들기로 했다.
커스텀 MySQL MCP 서버 작성
~/.claude/mcp-servers/mysql-ssl/ 디렉토리를 만들고 다음 파일들을 작성했다.
package.json
{
"name": "mysql-ssl-mcp",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"mysql2": "^3.9.0"
}
}
index.js
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import mysql from "mysql2/promise";
const config = {
host: process.env.MYSQL_HOST,
port: parseInt(process.env.MYSQL_PORT || "3306"),
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASS || process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DB || process.env.MYSQL_DATABASE,
// 핵심: SSL을 올바르게 설정
ssl: process.env.MYSQL_SSL === "true" ? { rejectUnauthorized: false } : undefined,
};
// ... MCP 서버 구현 (query, list_tables, describe_table 도구 제공)
핵심은 SSL 옵션을 { rejectUnauthorized: false }로 설정하는 것이다. 이렇게 하면 SSL 연결은 사용하되, 자체 서명 인증서나 AWS RDS 인증서도 허용한다.
MCP 서버 등록
의존성을 설치하고 Claude Code에 등록했다.
$ cd ~/.claude/mcp-servers/mysql-ssl
$ npm install
$ claude mcp add-json mysql '{
"type": "stdio",
"command": "node",
"args": ["/Users/suyoung/.claude/mcp-servers/mysql-ssl/index.js"],
"env": {
"MYSQL_HOST": "xxx.rds.amazonaws.com",
"MYSQL_PORT": "3306",
"MYSQL_USER": "plab_readonly",
"MYSQL_PASS": "xxx",
"MYSQL_DB": "plab",
"MYSQL_SSL": "true"
}
}' -s user
결과 확인
$ claude mcp list
mysql: node /Users/suyoung/.claude/mcp-servers/mysql-ssl/index.js - ✓ Connected
드디어 연결 성공!
정리
이번 문제의 원인은 크게 두 가지였다.
- 기존 패키지 삭제:
@benborgers/mysql-mcp패키지가 npm에서 삭제됨 - 대체 패키지의 SSL 버그:
@benborla29/mcp-server-mysql패키지가ssl: "enabled"라는 잘못된 값을 사용
해결책은 SSL을 올바르게 처리하는 커스텀 MCP 서버를 직접 작성하는 것이었다. 생각보다 MCP 서버를 만드는 건 어렵지 않다. @modelcontextprotocol/sdk 패키지를 사용하면 몇십 줄의 코드로 간단한 MCP 서버를 만들 수 있다.
AWS RDS처럼 SSL 연결이 필수인 환경에서 MySQL MCP를 사용하려면, 패키지의 SSL 구현을 확인해보거나 직접 만드는 것도 방법이다.
참고
'🌈 프로그래밍 > TIL' 카테고리의 다른 글
| Django ORM aggregate Sum이 NULL을 반환할 때 (1) | 2025.12.19 |
|---|---|
| Django ORM __in 조회에 딕셔너리 전달하면 어떻게 될까? (0) | 2025.12.18 |
| [ TIL ] 데이터베이스 정합성, DB Concurrency (0) | 2022.09.21 |
| [ FastAPI ] pytest를 사용해서 테스트 코드를 작성해보자 (0) | 2022.09.04 |
| [ TIL ] 모든 python 파일의 코드 스타일을 통일해보자 (with. Black) (0) | 2022.08.23 |