🌈 프로그래밍/TIL

Claude Code에서 MySQL MCP 서버 SSL 연결 문제 해결하기

수구리 2026. 1. 9. 11:31
반응형

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

드디어 연결 성공!

정리

이번 문제의 원인은 크게 두 가지였다.

  1. 기존 패키지 삭제: @benborgers/mysql-mcp 패키지가 npm에서 삭제됨
  2. 대체 패키지의 SSL 버그: @benborla29/mcp-server-mysql 패키지가 ssl: "enabled"라는 잘못된 값을 사용

해결책은 SSL을 올바르게 처리하는 커스텀 MCP 서버를 직접 작성하는 것이었다. 생각보다 MCP 서버를 만드는 건 어렵지 않다. @modelcontextprotocol/sdk 패키지를 사용하면 몇십 줄의 코드로 간단한 MCP 서버를 만들 수 있다.

AWS RDS처럼 SSL 연결이 필수인 환경에서 MySQL MCP를 사용하려면, 패키지의 SSL 구현을 확인해보거나 직접 만드는 것도 방법이다.

참고

반응형