MySQL MCP
Servidor MCP para MySQL/MariaDB — inspeção de esquemas, consultas e manipulação de dados para assistentes de IA
Documentação
Servidor MySQL MCP
Uma implementação de servidor de Protocolo de Contexto de Modelo (MCP) de alta qualidade para bancos de dados MySQL. Este servidor permite que assistentes de IA como o Claude interajam com bancos de dados MySQL por meio de um protocolo padronizado.
Versão: 0.2.0 | Protocolo: MCP 2025-03-26 | Rust: 1.70+ | Status: Pronto para Produção
Sumário
- Recursos
- Instalação
- Início Rápido (5 Minutos)
- Uso
- Ferramentas Disponíveis
- Recurso de Contexto de Banco de Dados
- Considerações de Segurança
- Arquitetura
- Solução de Problemas
- Desenvolvimento
- Guia de Implantação
- Contribuição
- Licença
- Suporte
Recursos
- Inspeção de Esquema: Recuperar esquemas de tabelas e informações de estrutura
- Execução de Consultas: Executar consultas SQL (somente leitura por padrão para segurança)
- Manipulação de Dados: Operações de inserção, atualização e exclusão
- Contexto de Banco de Dados: Especificar qual banco de dados usar por consulta
- Controles de Segurança: Restrições de consulta configuráveis para evitar operações perigosas
- Gerenciamento de Conexões: Tratamento robusto de conexões com lógica de repetição e pooling
- Tratamento de Erros: Relatórios abrangentes de erros com mensagens detalhadas
- Protocolo JSON-RPC 2.0: Comunicação padronizada via stdio
Instalação
Pré-requisitos
- Rust 1.70+
- MySQL 5.7+ ou MariaDB 10.2+
- Acesso a um banco de dados MySQL
Compilação a partir do Código Fonte
git clone <repository-url>
cd mcp-server-mysql
cargo build --release
O binário compilado estará disponível em target/release/mcp-server-mysql.
A partir do Pacote de Lançamento
# Extract the package
tar -xzf mcp-server-mysql-v0.2.0-linux-x86_64.tar.gz
# Move binary to system path (optional)
sudo cp mcp-server-mysql /usr/local/bin/
# Verify installation
mcp-server-mysql --version
Início Rápido (5 Minutos)
Etapa 1: Compilar o Servidor
cargo build --release
O binário estará em target/release/mcp-server-mysql
Etapa 2: Testar a Conexão
./target/release/mcp-server-mysql \
--host localhost \
--username root \
--password yourpassword \
--database testdb
Você deverá ver: "Servidor MySQL MCP iniciado e pronto para aceitar conexões"
Etapa 3: Configurar o Claude Desktop
Edite o arquivo de configuração do Claude Desktop:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Adicione esta configuração:
{
"mcpServers": {
"mysql": {
"command": "/absolute/path/to/mcp-server-mysql",
"args": [
"--host", "localhost",
"--port", "3306",
"--username", "your_username",
"--password", "your_password",
"--database", "your_database"
]
}
}
}
Nota de Segurança: Para uso em produção, considere usar variáveis de ambiente ou uma solução segura de gerenciamento de segredos em vez de codificar senhas no arquivo de configuração.
Etapa 4: Reiniciar o Claude Desktop
Feche e reabra o Claude Desktop completamente. Você deverá ver um pequeno ícone de martelo indicando que o servidor MCP está conectado.
Etapa 5: Experimente!
Pergunte ao Claude:
- "Você pode me mostrar o esquema da tabela de usuários no meu banco de dados MySQL?"
- "Consulte o banco de dados e me mostre as primeiras 10 linhas da tabela de produtos"
- "Quais tabelas existem no meu banco de dados?"
Uso
Argumentos de Linha de Comando
mcp-server-mysql \
--host localhost \
--port 3306 \
--username your_username \
--password your_password \
--database your_database \
--allow-dangerous-queries false
Referência de Argumentos
| Argumento | Descrição | Padrão | Obrigatório |
|---|---|---|---|
--host | Hostname do servidor MySQL | localhost | Não |
--port | Porta do servidor MySQL | 3306 | Não |
--username | Nome de usuário do MySQL | - | Sim |
--password | Senha do MySQL | (vazio) | Não |
--database | Nome do banco de dados para conectar | - | Sim |
--allow-dangerous-queries | Permitir consultas INSERT/UPDATE/DELETE | false | Não |
Configuração com o Claude Desktop
Adicione esta configuração ao arquivo de configuração do Claude Desktop:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mysql": {
"command": "/path/to/mcp-server-mysql",
"args": [
"--host", "localhost",
"--port", "3306",
"--username", "your_username",
"--password", "your_password",
"--database", "your_database"
]
}
}
}
Ferramentas Disponíveis
1. mysql (Inspeção de Esquema)
Recuperar informações de esquema de banco de dados para tabelas.
Parâmetros:
table_name(string): Nome da tabela a inspecionar, ou"all-tables"para obter todos os esquemas de tabelas
Exemplo:
{
"table_name": "users"
}
Retorna:
- Informações de colunas (nome, tipo, anulável, padrões, chaves)
- Informações de índices
- Restrições de tabela
2. query (Execução de SQL)
Executar consultas SQL no banco de dados.
Parâmetros:
query(string): Consulta SQL a executardatabase(string, opcional): Nome do banco de dados a usar para esta consulta específica
Exemplo:
{
"query": "SELECT * FROM users WHERE active = 1 LIMIT 10",
"database": "my_database"
}
Segurança:
- Por padrão, apenas consultas SELECT são permitidas
- Use o sinalizador
--allow-dangerous-queriespara habilitar INSERT/UPDATE/DELETE - Palavras-chave perigosas são bloqueadas a menos que explicitamente habilitadas
3. insert (Inserir Dados)
Inserir dados em uma tabela especificada.
Parâmetros:
table_name(string): Nome da tabeladata(objeto): Pares chave-valor de nomes de colunas e valores
Exemplo:
{
"table_name": "users",
"data": {
"username": "john_doe",
"email": "john@example.com",
"active": true
}
}
Retorna: Último ID de inserção
4. update (Atualizar Dados)
Atualizar dados em uma tabela especificada com base em condições.
Parâmetros:
table_name(string): Nome da tabeladata(objeto): Pares chave-valor de colunas a atualizarconditions(objeto): Pares chave-valor para a cláusula WHERE
Exemplo:
{
"table_name": "users",
"data": {
"email": "newemail@example.com",
"updated_at": "2024-01-15 10:30:00"
},
"conditions": {
"id": 123
}
}
Retorna: Número de linhas afetadas
5. delete (Excluir Dados)
Excluir dados de uma tabela especificada com base em condições.
Parâmetros:
table_name(string): Nome da tabelaconditions(objeto): Pares chave-valor para a cláusula WHERE
Exemplo:
{
"table_name": "users",
"conditions": {
"id": 123
}
}
Retorna: Número de linhas afetadas
Aviso: Sempre especifique condições para evitar excluir todas as linhas!
Recurso de Contexto de Banco de Dados
O Problema
Anteriormente, o contexto do banco de dados não era mantido entre consultas:
-- Query 1
USE dev_database; -- Succeeds
-- Query 2 (new connection from pool)
SELECT * FROM my_table; -- ❌ Fails: context was lost
A Solução
Use o parâmetro opcional database em cada consulta:
{
"query": "SELECT * FROM my_table",
"database": "dev_database"
}
Benefícios
- Explícito e Claro: Saiba exatamente qual banco de dados cada consulta usa
- Sem Estado Oculto: Cada consulta é independente
- Compatível com Versões Anteriores: Consultas existentes sem parâmetro ainda funcionam
- Sem Condições de Corrida: Cada consulta obtém sua própria conexão
- Simples de Usar: Basta adicionar
"database": "name"aos argumentos da consulta
Exemplos de Uso
Consulta Básica com Parâmetro de Banco de Dados
{
"query": "SELECT * FROM crm_sites LIMIT 10",
"database": "dev_smartConnect_za"
}
Consulta Sem Parâmetro de Banco de Dados (Usa o Padrão)
{
"query": "SELECT * FROM users WHERE active = 1"
}
Usa o banco de dados especificado no argumento de inicialização --database.
Múltiplos Bancos de Dados na Mesma Sessão
// Query database 1
{
"query": "SELECT COUNT(*) FROM customers",
"database": "production_db"
}
// Query database 2
{
"query": "SELECT COUNT(*) FROM test_data",
"database": "test_db"
}
Antes vs Depois
Antes (Nomes totalmente qualificados necessários):
SELECT * FROM dev_smartConnect_za.crm_sites
JOIN dev_smartConnect_za.crm_orgs ON ...
WHERE dev_smartConnect_za.crm_sites.active = 1;
Depois (Limpo e simples):
{
"query": "SELECT * FROM crm_sites JOIN crm_orgs ON ... WHERE active = 1",
"database": "dev_smartConnect_za"
}
Cenários Comuns
Cenário 1: Projeto de Banco de Dados Único
Defina o banco de dados padrão e omita o parâmetro:
# Startup
--database my_project_db
# Query (no database parameter needed)
{
"query": "SELECT * FROM users"
}
Cenário 2: Projeto de Múltiplos Bancos de Dados
Especifique o banco de dados para cada consulta:
// Customer database
{ "query": "...", "database": "customers_db" }
// Orders database
{ "query": "...", "database": "orders_db" }
// Analytics database
{ "query": "...", "database": "analytics_db" }
Tratamento de Erros
Código de Erro -32005: Falha na Aquisição de Conexão
Cause: Connection pool exhausted
Solution: Retry after a moment
Código de Erro -32006: Falha na Troca de Contexto de Banco de Dados
Cause: Database doesn't exist or user lacks permissions
Solution: Verify database exists and user has access
Melhores Práticas
✅ FAÇA
- Especifique o banco de dados explicitamente para consultas de produção
- Use nomes descritivos de banco de dados em suas consultas
- Teste com
SELECT DATABASE()para verificar o contexto - Agrupe consultas por banco de dados para clareza
❌ NÃO FAÇA
- Misture nomes qualificados e não qualificados na mesma consulta
- Presuma persistência - especifique o banco de dados para cada consulta
- Use caracteres especiais em nomes de banco de dados, se possível
- Esqueça de verificar as permissões do usuário para todos os bancos de dados
Considerações de Segurança
Modo Somente Leitura (Padrão)
Por padrão, o servidor opera em modo somente leitura, permitindo apenas consultas SELECT. Isso evita modificação ou exclusão acidental de dados.
Modo de Consultas Perigosas
Habilite operações de escrita com --allow-dangerous-queries:
mcp-server-mysql --username user --password pass --database mydb --allow-dangerous-queries true
Use com cautela! Isso habilita:
- Instruções INSERT
- Instruções UPDATE
- Instruções DELETE
- Outras operações potencialmente destrutivas
Proteção contra Injeção de SQL
- Nomes de tabelas são validados para conter apenas caracteres alfanuméricos e sublinhados
- Todos os valores de dados são parametrizados usando instruções preparadas
- Nomes de banco de dados são escapados substituindo crases por crases duplas
- Nenhuma concatenação SQL bruta é realizada
Segurança de Conexão
- Suporta conexões SSL/TLS padrão do MySQL
- Strings de conexão podem ser configuradas com segurança
- Senhas podem ser fornecidas via variáveis de ambiente
- Considere usar usuários de banco de dados dedicados com permissões limitadas
Segurança de Implantação em Produção
-
Use usuário de banco de dados dedicado:
CREATE USER 'mcp_user'@'localhost' IDENTIFIED BY 'secure_password'; GRANT SELECT ON your_database.* TO 'mcp_user'@'localhost'; FLUSH PRIVILEGES; -
Habilite acesso de escrita apenas quando necessário:
--allow-dangerous-queries true # Use with caution! -
Use variáveis de ambiente (melhoria futura): Considere envolver o binário em um script de shell que lê de variáveis de ambiente.
Arquitetura
Visão Geral do Sistema
┌─────────────────────────────────────────────────────┐
│ MCP Client (e.g., Claude) │
│ Sends: {query, database} │
└────────────────────────┬────────────────────────────┘
│ JSON-RPC 2.0 (stdio)
▼
┌─────────────────────────────────────────────────────┐
│ MCP MySQL Server (Rust) │
│ │
│ execute_query(query, database, pool) │
│ ├─ If database param: │
│ │ ├─ Acquire connection from pool │
│ │ ├─ Execute: USE `database` │
│ │ └─ Execute: [user's query] │
│ └─ Else: │
│ └─ Execute query on pool (default database) │
└────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ MySQL Connection Pool (5 connections) │
└────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ MySQL/MariaDB Server │
└─────────────────────────────────────────────────────┘
Sequência: Consulta com Parâmetro de Banco de Dados
Client MCP Server Connection Pool MySQL Server
│ │ │ │
│ query + │ │ │
│ database │ │ │
├────────────────>│ │ │
│ │ │ │
│ │ acquire() │ │
│ ├───────────────────>│ │
│ │ <connection> │ │
│ │<───────────────────┤ │
│ │ │ │
│ │ USE database │ │
│ ├────────────────────┼─────────────────>│
│ │ OK │ │
│ │<────────────────────┼──────────────────┤
│ │ │ │
│ │ SELECT query │ │
│ ├────────────────────┼─────────────────>│
│ │ Results │ │
│ │<────────────────────┼──────────────────┤
│ │ │ │
│ │ release() │ │
│ ├───────────────────>│ │
│ Results │ │ │
│<────────────────┤ │ │
Gerenciamento do Pool de Conexões
Pool (5 connections)
┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐
│ C1 │ │ C2 │ │ C3 │ │ C4 │ │ C5 │
└────┘ └────┘ └────┘ └────┘ └────┘
Key Properties:
• Each query gets its own connection instance
• Database context is set per connection, per query
• No state persists between queries
• Fully thread-safe and concurrent
Detalhes Técnicos
- Versão do Protocolo: MCP 2025-03-26
- Transporte: stdio (JSON-RPC 2.0)
- Pooling de Conexões: Máximo de 5 conexões
- Lógica de Repetição: Reconexão automática em falhas transitórias
- Sobrecarga de Desempenho: ~50-200 microssegundos por consulta com parâmetro de banco de dados
Solução de Problemas
Falhas de Conexão
Se você encontrar erros de conexão:
-
Verifique se o MySQL está em execução:
mysql -h localhost -u your_username -p -
Verifique as credenciais:
- Certifique-se de que o nome de usuário e a senha estão corretos
- Confirme que o usuário tem acesso ao banco de dados especificado
-
Verifique o acesso à rede:
- Verifique se o host e a porta estão corretos
- Certifique-se de que nenhum firewall está bloqueando a conexão
-
Revise os logs do servidor:
- O servidor registra logs em stderr
- Verifique mensagens de erro detalhadas
Erros Comuns
"Falha na conexão com o banco de dados"
- O servidor MySQL pode não estar em execução
- Configuração incorreta de host/porta
- Problemas de conectividade de rede
"Apenas consultas SELECT são permitidas"
- Você está tentando executar uma consulta de escrita no modo somente leitura
- Adicione
--allow-dangerous-queries truese o acesso de escrita for necessário
"Nenhum banco de dados selecionado"
- O banco de dados especificado não existe
- O usuário não tem acesso ao banco de dados
- Verifique
SHOW DATABASES;para ver os bancos de dados disponíveis
"A tabela não existe"
- Verifique se você está consultando o banco de dados correto
- Adicione o parâmetro
databasese estiver usando múltiplos bancos de dados - Use
SELECT DATABASE()para verificar o contexto atual
"Falha ao adquirir conexão"
- O pool de conexões está esgotado
- Aguarde um momento e tente novamente
Ferramenta não aparecendo no Claude Desktop
- Verifique se o caminho para o binário é absoluto (não relativo)
- Verifique os logs do Claude Desktop para erros
- Reinicie o Claude Desktop completamente (não apenas recarregue)
- Certifique-se de que o processo do servidor inicia sem erros quando executado manualmente
Desenvolvimento
Estrutura do Projeto
mcp-server-mysql/
├── src/
│ ├── main.rs # Main server implementation
│ ├── config.rs # Configuration handling
│ ├── db.rs # Database operations
│ ├── rpc.rs # RPC protocol handling
│ └── server.rs # Server initialization
├── tests/ # Test files
├── Cargo.toml # Rust dependencies
├── Cargo.lock # Locked dependency versions
└── README.md # This file
Compilação para Desenvolvimento
cargo build
cargo run -- --help
Executando Testes
cargo test
Qualidade do Código
# Format code
cargo fmt
# Run linter
cargo clippy
# Check for issues
cargo check
Convenções de Desenvolvimento
O projeto segue as melhores práticas padrão do Rust:
- Formatação de código:
cargo fmt - Linting:
cargo clippy - Testes:
cargo test
Guia de Implantação
Implantação Rápida
1. Testar Conexão
./mcp-server-mysql \
--username your_user \
--password your_pass \
--database your_db
Pressione Ctrl+C para sair após ver "Servidor MySQL MCP iniciado".
2. Configurar o Claude Desktop
Edite o arquivo de configuração do Claude e adicione a configuração do servidor (consulte a seção Início Rápido).
3. Reiniciar o Claude Desktop
Feche e reabra o Claude Desktop completamente.
Dicas de Implantação em Produção
Desempenho
- O binário é otimizado com o sinalizador
--release - O pooling de conexões está configurado (máximo de 5 conexões)
- Lógica de repetição automática para falhas transitórias
Monitoramento
Os logs do servidor vão para stderr. Capture-os com:
./mcp-server-mysql --username user --password pass --database db 2>> server.log
Níveis de log:
INFO: Eventos de conexão, chamadas de ferramentasDEBUG: Informações detalhadas de consultasWARN: Problemas não fataisERROR: Falhas e erros
Serviço Systemd (Opcional)
Para implantações de longa duração, crie /etc/systemd/system/mcp-mysql.service:
[Unit]
Description=MySQL MCP Server
After=network.target mysql.service
[Service]
Type=simple
User=mcp-user
ExecStart=/usr/local/bin/mcp-server-mysql --username mcp_user --password secret --database production
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Habilite e inicie:
sudo systemctl enable mcp-mysql
sudo systemctl start mcp-mysql
sudo systemctl status mcp-mysql
Atualização
# Backup current version
cp /usr/local/bin/mcp-server-mysql /usr/local/bin/mcp-server-mysql.backup
# Replace with new version
cp mcp-server-mysql /usr/local/bin/
# Restart services
sudo systemctl restart mcp-mysql # If using systemd
# Or restart Claude Desktop
Reversão
# Restore previous version
cp /usr/local/bin/mcp-server-mysql.backup /usr/local/bin/mcp-server-mysql
# Or checkout previous git tag
git checkout v0.1.0
cargo build --release
Contribuição
Contribuições são bem-vindas! Por favor, garanta:
- O código segue as melhores práticas do Rust
- Todos os testes passam
- A documentação é atualizada
- As mensagens de commit são claras e descritivas
Licença
Apache-2.0
Suporte
Para problemas, perguntas ou contribuições, abra uma issue no repositório do projeto.
Versão: 0.2.0 | Data de lançamento: 2025-01-XX | Protocolo: MCP 2025-03-26 | Plataforma: Linux x86_64 | Status: Pronto para produção ✅