haroldorg-mcp-server-oracle-database
v1.0.1
Published
Executa operações em bases de dados ORACLE Server usando o Model Context Protocol (MCP).
Maintainers
Readme
MCP Oracle Database Server
Um servidor Model Context Protocol (MCP) robusto para Oracle Database que permite executar consultas seguras, explorar metadados e pesquisar packages, procedures e functions.
📋 Funcionalidades
- ✅ Execução segura de consultas SELECT com validação rigorosa
- ✅ Consulta abrangente de metadados (TABLES, VIEWS, COLUMNS)
- ✅ Busca avançada de Packages com múltiplas estratégias
- ✅ Busca avançada de Procedures (standalone ou dentro de packages)
- ✅ Pesquisa de Functions (scalar, table-valued, standalone ou dentro de packages)
- ✅ Análise de Procedures/Functions com busca por tabelas/colunas referenciadas
- ✅ Obtenção do código-fonte completo de packages e procedures
- ✅ Proteção contra comandos DDL/DML perigosos
- ✅ Suporte completo a parâmetros SQL (prevenção de SQL injection)
- ✅ Pool de conexões com reconexão automática
- ✅ Resiliência aprimorada com retry automático
🛠️ Ferramentas Disponíveis
1. executeQuery
Executa uma query SELECT segura nas tabelas/views do banco de dados Oracle.
Parâmetros:
query(string, obrigatório): Comando SQL SELECT a ser executadoparams(object, opcional): Parâmetros SQL para a query (bind variables)
Validações:
- Apenas comandos SELECT são permitidos
- Comandos DDL/DML (UPDATE, DELETE, INSERT, ALTER, DROP, CREATE, etc.) são bloqueados
- Comentários SQL são removidos antes da validação
- Suporte a bind variables Oracle (
:param_name)
Exemplo:
{
"query": "SELECT * FROM users WHERE status = :status AND created_date > :created_date",
"params": {
"status": "active",
"created_date": "2024-01-01"
}
}2. getDatabaseMetadata
Consulta metadados do banco de dados Oracle com filtros opcionais.
Parâmetros:
type(string, obrigatório): Tipo de metadado - TABLES, VIEWS ou COLUMNSfilters(object, opcional): Filtros para a consulta
Tipos de Metadados Disponíveis:
TABLES
Consulta tabelas do banco de dados Oracle (ALL_TABLES).
- Retorna: OWNER, TABLE_NAME, TABLESPACE_NAME, STATUS, NUM_ROWS
- Filtros disponíveis:
OWNER: Schema/owner da tabela (VARCHAR2, 128)TABLE_NAME: Nome da tabela (VARCHAR2, 128)TABLESPACE_NAME: Nome do tablespace (VARCHAR2, 30)STATUS: Status da tabela (VARCHAR2, 8)NUM_ROWS: Número de linhas (NUMBER)
VIEWS
Consulta views do banco de dados Oracle (ALL_VIEWS).
- Retorna: OWNER, VIEW_NAME, TEXT_LENGTH
- Filtros disponíveis:
OWNER: Schema/owner da view (VARCHAR2, 128)VIEW_NAME: Nome da view (VARCHAR2, 128)TEXT_LENGTH: Comprimento do texto da view (NUMBER)
COLUMNS
Consulta colunas das tabelas e views (ALL_TAB_COLUMNS). Obrigatório usar filtro: TABLE_NAME OU COLUMN_NAME
- Retorna: OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_LENGTH, NULLABLE, COLUMN_ID
- Filtros disponíveis:
OWNER: Schema/owner (VARCHAR2, 128)TABLE_NAME: Nome da tabela (VARCHAR2, 128)COLUMN_NAME: Nome da coluna com suporte LIKE (VARCHAR2, 128)DATA_TYPE: Tipo de dados (VARCHAR2, 128)DATA_LENGTH: Comprimento dos dados (NUMBER)NULLABLE: Permite NULL? (VARCHAR2, 1)COLUMN_ID: ID da coluna (NUMBER)
Exemplos:
// Listar todas as tabelas
{
"type": "TABLES"
}
// Listar tabelas de um schema específico
{
"type": "TABLES",
"filters": {
"OWNER": "HR"
}
}
// Obter colunas de uma tabela específica
{
"type": "COLUMNS",
"filters": {
"TABLE_NAME": "EMPLOYEES"
}
}
// Buscar colunas que contenham "id" no nome
{
"type": "COLUMNS",
"filters": {
"COLUMN_NAME": "id"
}
}
// Listar todas as views
{
"type": "VIEWS"
}
// Listar views de um schema específico
{
"type": "VIEWS",
"filters": {
"OWNER": "HR"
}
}3. searchPackagesAndProcedures
Pesquisa avançada de packages e procedures com múltiplas estratégias.
Parâmetros:
operation(string, obrigatório): Tipo de operação- Parâmetros específicos conforme a operação
Operações Disponíveis:
SEARCH_PACKAGES_BY_NAME
Busca packages cujo nome corresponde ao padrão informado (suporta LIKE).
- Parâmetros:
name_pattern(obrigatório),owner(opcional) - Exemplo:
name_pattern: "%CLAIM%"ouname_pattern: "HR_UTILS"
SEARCH_PACKAGES_BY_TABLE
Busca packages cujo corpo (PACKAGE BODY) referencia o nome da tabela informada.
- Parâmetros:
table_name(obrigatório),owner(opcional)
SEARCH_PACKAGES_BY_COLUMN
Busca packages cujo corpo (PACKAGE BODY) referencia o nome da coluna/campo informado.
- Parâmetros:
column_name(obrigatório),owner(opcional)
LIST_PACKAGE_PROCEDURES
Lista as procedures e functions definidas dentro de uma package específica.
- Parâmetros:
package_name(obrigatório),owner(opcional) - Retorna: Nome da procedure, tipo, overload, id do subprogram
SEARCH_PROCEDURES_BY_TABLE
Busca procedures e functions (standalone ou dentro de packages) que referenciam a tabela informada. Retorna o nome do objeto (package ou procedure), o tipo e o nome da procedure/function contextual.
- Parâmetros:
table_name(obrigatório),owner(opcional)
SEARCH_PROCEDURES_BY_COLUMN
Busca procedures e functions (standalone ou dentro de packages) que referenciam a coluna informada.
- Parâmetros:
column_name(obrigatório),owner(opcional)
GET_PACKAGE_BODY
Retorna o código-fonte completo (PACKAGE BODY) de uma package. O resultado é agrupado em um único campo 'source'.
- Parâmetros:
package_name(obrigatório),owner(opcional)
GET_PROCEDURE_BODY
Retorna o código-fonte completo de uma procedure autônoma (não pertencente a uma package). O resultado é agrupado em um único campo 'source'.
- Parâmetros:
procedure_name(obrigatório),owner(opcional)
Exemplos:
// Buscar packages por nome
{
"operation": "SEARCH_PACKAGES_BY_NAME",
"name_pattern": "%CLAIM%"
}
// Buscar packages que usam uma tabela
{
"operation": "SEARCH_PACKAGES_BY_TABLE",
"table_name": "CLAIMS",
"owner": "INSURANCE"
}
// Buscar packages que usam uma coluna
{
"operation": "SEARCH_PACKAGES_BY_COLUMN",
"column_name": "claim_id",
"owner": "INSURANCE"
}
// Listar procedures dentro de uma package
{
"operation": "LIST_PACKAGE_PROCEDURES",
"package_name": "PKG_CLAIMS",
"owner": "INSURANCE"
}
// Buscar procedures que referenciam uma tabela
{
"operation": "SEARCH_PROCEDURES_BY_TABLE",
"table_name": "CLAIMS"
}
// Buscar procedures que referenciam uma coluna
{
"operation": "SEARCH_PROCEDURES_BY_COLUMN",
"column_name": "status"
}
// Obter código-fonte de um package
{
"operation": "GET_PACKAGE_BODY",
"package_name": "PKG_CLAIMS",
"owner": "INSURANCE"
}
// Obter código-fonte de uma procedure standalone
{
"operation": "GET_PROCEDURE_BODY",
"procedure_name": "SP_GET_CLAIM_DETAILS",
"owner": "INSURANCE"
}4. searchFunctions
Pesquisa avançada de functions com múltiplas estratégias.
Parâmetros:
operation(string, obrigatório): Tipo de operação- Parâmetros específicos conforme a operação
Operações Disponíveis:
SEARCH_FUNCTIONS_BY_NAME
Busca functions cujo nome corresponde ao padrão informado (suporta LIKE). Retorna tanto functions standalone quanto functions definidas dentro de packages.
- Parâmetros:
name_pattern(obrigatório),owner(opcional) - Exemplo:
name_pattern: "%GET_CLAIM%"ouname_pattern: "FN_CALCULATE_AGE"
SEARCH_FUNCTIONS_BY_TABLE
Busca functions (standalone ou dentro de packages) cujo código-fonte referencia o nome da tabela informada.
- Parâmetros:
table_name(obrigatório),owner(opcional)
SEARCH_FUNCTIONS_BY_COLUMN
Busca functions (standalone ou dentro de packages) cujo código-fonte referencia o nome do campo/coluna informado.
- Parâmetros:
column_name(obrigatório),owner(opcional)
GET_FUNCTION_BODY
Retorna o código-fonte completo de uma function. Para functions standalone, informe apenas function_name. Para functions dentro de um package, informe function_name e package_name (retornará o body completo do package).
- Parâmetros:
function_name(obrigatório),package_name(opcional),owner(opcional)
Exemplos:
// Buscar functions por nome
{
"operation": "SEARCH_FUNCTIONS_BY_NAME",
"name_pattern": "%GET_CLAIM%"
}
// Buscar functions que usam uma tabela
{
"operation": "SEARCH_FUNCTIONS_BY_TABLE",
"table_name": "CLAIMS",
"owner": "INSURANCE"
}
// Buscar functions que usam uma coluna
{
"operation": "SEARCH_FUNCTIONS_BY_COLUMN",
"column_name": "claim_id"
}
// Obter código-fonte de uma function standalone
{
"operation": "GET_FUNCTION_BODY",
"function_name": "FN_CALCULATE_AGE",
"owner": "HR"
}
// Obter código-fonte de uma function dentro de package
{
"operation": "GET_FUNCTION_BODY",
"function_name": "GET_CLAIM_STATUS",
"package_name": "PKG_CLAIMS",
"owner": "INSURANCE"
}🚀 Instalação e Configuração
Requisitos
- Node.js 16+
- Oracle Database (11g+) ou Oracle Cloud Database
- npm ou yarn
Opção 1: Executar Localmente (Desenvolvimento)
- Clone o repositório:
git clone <url-do-repositorio>
cd mcp-server-oracle-database- Instale as dependências:
npm install- Configure a conexão (.env):
Crie um arquivo
.envna raiz do projeto com suas credenciais Oracle:
# Credenciais Oracle
ORACLE_USER=seu_usuario
ORACLE_PASSWORD=sua_senha
ORACLE_HOST=seu_host_oracle
ORACLE_PORT=1521
ORACLE_SERVICE_NAME=seu_service_name
# Configuração de resiliência (opcionais)
ORACLE_MAX_RECONNECT_ATTEMPTS=5
ORACLE_RECONNECT_DELAY_MS=5000- Compile o TypeScript:
npm run build- Inicie o servidor MCP:
npm run mcpOpção 2: Usar via NPM (Recomendado para Produção)
- Instale o pacote globalmente:
npm install -g haroldorg-mcp-server-oracle-database- Configure as variáveis de ambiente:
export ORACLE_USER=seu_usuario
export ORACLE_PASSWORD=sua_senha
export ORACLE_HOST=seu_host_oracle
export ORACLE_PORT=1521
export ORACLE_SERVICE_NAME=seu_service_name- Execute o servidor:
haroldorg-mcp-server-oracle-databaseConfiguração no VS Code
Edite o arquivo .vscode/mcp.json (ou mcp.json global do VS Code) com a seguinte configuração:
{
"mcp": {
"servers": {
"haroldorg-mcp-server-oracle-database": {
"type": "stdio",
"command": "npx",
"args": ["haroldorg-mcp-server-oracle-database"],
"env": {
"ORACLE_USER": "seu_usuario",
"ORACLE_PASSWORD": "sua_senha",
"ORACLE_HOST": "seu_host_oracle",
"ORACLE_PORT": "1521",
"ORACLE_SERVICE_NAME": "seu_service_name",
"ORACLE_MAX_RECONNECT_ATTEMPTS": "5",
"ORACLE_RECONNECT_DELAY_MS": "5000"
}
}
}
}
}Ou para desenvolvimento local:
{
"mcp": {
"servers": {
"haroldorg-mcp-server-oracle-database": {
"type": "stdio",
"command": "node",
"args": ["C:\\caminho\\completo\\para\\dist\\mcp-server.js"],
"env": {
"ORACLE_USER": "seu_usuario",
"ORACLE_PASSWORD": "sua_senha",
"ORACLE_HOST": "seu_host_oracle",
"ORACLE_PORT": "1521",
"ORACLE_SERVICE_NAME": "seu_service_name",
"ORACLE_MAX_RECONNECT_ATTEMPTS": "10",
"ORACLE_RECONNECT_DELAY_MS": "3000"
}
}
}
}
}⚙️ Configuração da Conexão Oracle
A conexão Oracle é estabelecida usando as variáveis de ambiente. Abaixo estão exemplos para diferentes cenários:
Conexão com Instância Local
ORACLE_USER=sys
ORACLE_PASSWORD=oracle
ORACLE_HOST=localhost
ORACLE_PORT=1521
ORACLE_SERVICE_NAME=ORCLConexão com Instância Remota
ORACLE_USER=schema_user
ORACLE_PASSWORD=senha_segura
ORACLE_HOST=db.empresa.com
ORACLE_PORT=1521
ORACLE_SERVICE_NAME=PROD_DBConexão com Oracle Cloud
ORACLE_USER=seu_usuario@seu_dominio
ORACLE_PASSWORD=sua_senha
ORACLE_HOST=seu_host_oracle_cloud
ORACLE_PORT=1521
ORACLE_SERVICE_NAME=seu_service_name_cloudVariáveis de Resiliência (Opcionais)
Configure a reconexão automática com variáveis de ambiente:
# Número máximo de tentativas de reconexão (padrão: 5)
ORACLE_MAX_RECONNECT_ATTEMPTS=10
# Intervalo entre tentativas em milissegundos (padrão: 5000 = 5 segundos)
ORACLE_RECONNECT_DELAY_MS=3000🔒 Segurança
Proteções Implementadas
- Whitelist de Comandos: Apenas
SELECTé permitido - Bloqueio de Comandos Perigosos: DDL/DML são rejeitados automaticamente
- Bloqueados: UPDATE, DELETE, INSERT, ALTER, DROP, CREATE, TRUNCATE, RENAME, GRANT, REVOKE, MERGE, CALL, EXEC, EXECUTE
- Bind Variables: Suporte completo com proteção contra SQL injection
- Remoção de Comentários: Comentários SQL são removidos antes da validação
- Validação Rigorosa: Múltiplas camadas de verificação de segurança
- Reconexão Automática: Detect erros de conectividade e reconecta automaticamente
- Autenticação OAuth: Suporte a variáveis de ambiente seguras
Boas Práticas
- Sempre use bind variables em vez de concatenar strings
- Valide filters de metadados obrigatoriamente para COLUMNS
- Use HTTPS em ambientes de produção com VS Code
- Restrinja permissões do banco ao mínimo necessário (schema específico, read-only)
- Monitore logs de erro para possíveis tentativas de ataque
- Use credenciais diferentes por ambiente (dev, staging, prod)
- Rotacione senhas regularmente
- Não exponha .env em controle de versão (use .gitignore)
📁 Estrutura do Projeto
├── src/
│ ├── app.ts # Aplicação Express (opcional)
│ ├── mcp-server.ts # Servidor MCP principal
│ ├── oraclePool.ts # Pool de conexões com resiliência
│ ├── controllers/
│ │ └── DatabaseController.ts # Lógica de negócio
│ └── routes/
│ └── DatabaseRoutes.ts # Rotas Express (opcional)
├── dist/ # Código compilado
├── package.json
├── tsconfig.json
└── README.mdDescrição dos Arquivos
mcp-server.ts
Servidor MCP principal que:
- Define as ferramentas disponíveis (executeQuery, getDatabaseMetadata, searchPackagesAndProcedures, searchFunctions)
- Implementa os handlers para requisições de ferramenta
- Gerencia a conexão com o banco de dados
- Implementa retry automático em caso de desconexão
oraclePool.ts
Pool de conexões Oracle com:
- Gerenciamento de conexões ativas
- Reconexão automática com retry exponencial
- Callbacks para quando o pool é atualizado
- Detecção de erros relacionados à conectividade
- Suporte a configuração de resiliência via variáveis de ambiente
controllers/DatabaseController.ts
Controlador com a lógica de negócio:
executeQuery(): Executa queries SELECT com validaçãogetDatabaseMetadata(): Consulta metadados de tabelas, views e colunassearchPackagesAndProcedures(): Pesquisa packages e proceduressearchFunctions(): Pesquisa functions
routes/DatabaseRoutes.ts
Rotas Express para acesso HTTP (opcional):
GET /database/metadata: Consulta metadadosPOST /database/query: Executa queries
app.ts
Aplicação Express para acesso via HTTP (opcional para desenvolvimento local).
🧪 Scripts Disponíveis
# Executar em modo desenvolvimento (via Express)
npm start
# Executar servidor MCP (recomendado)
npm run mcp
# Compilar TypeScript para JavaScript
npm run build
# Executar testes (não configurado)
npm test📝 Exemplos de Uso Avançados
Exemplo 1: Explorar Estrutura de Banco
// 1. Listar todas as tabelas
{
"name": "getDatabaseMetadata",
"arguments": {
"type": "TABLES"
}
}
// 2. Obter colunas de uma tabela específica
{
"name": "getDatabaseMetadata",
"arguments": {
"type": "COLUMNS",
"filters": { "TABLE_NAME": "EMPLOYEES" }
}
}
// 3. Listar todas as views
{
"name": "getDatabaseMetadata",
"arguments": {
"type": "VIEWS"
}
}Exemplo 2: Pesquisar e Obter Código de Package
// 1. Buscar packages que usam uma tabela
{
"name": "searchPackagesAndProcedures",
"arguments": {
"operation": "SEARCH_PACKAGES_BY_TABLE",
"table_name": "EMPLOYEES",
"owner": "HR"
}
}
// 2. Obter código-fonte completo da package
{
"name": "searchPackagesAndProcedures",
"arguments": {
"operation": "GET_PACKAGE_BODY",
"package_name": "PKG_HR_UTILS",
"owner": "HR"
}
}
// 3. Listar procedures dentro da package
{
"name": "searchPackagesAndProcedures",
"arguments": {
"operation": "LIST_PACKAGE_PROCEDURES",
"package_name": "PKG_HR_UTILS",
"owner": "HR"
}
}Exemplo 3: Pesquisar Functions
// Buscar functions que referenciam uma coluna
{
"name": "searchFunctions",
"arguments": {
"operation": "SEARCH_FUNCTIONS_BY_COLUMN",
"column_name": "employee_id",
"owner": "HR"
}
}
// Obter definição de uma function
{
"name": "searchFunctions",
"arguments": {
"operation": "GET_FUNCTION_BODY",
"function_name": "FN_CALCULATE_SALARY",
"owner": "HR"
}
}Exemplo 4: Executar Consulta Segura
{
"name": "executeQuery",
"arguments": {
"query": "SELECT emp_id, emp_name, salary, department FROM employees WHERE department = :dept AND salary > :min_salary ORDER BY salary DESC",
"params": {
"dept": "SALES",
"min_salary": "50000"
}
}
}🐛 Troubleshooting
Erro: "Conexão recusada"
- ✅ Verifique se o Oracle Database está em execução
- ✅ Confirme se o HOST, PORT e SERVICE_NAME estão corretos na configuração
- ✅ Teste a conectividade:
tnsping seu_service_name - ✅ Verifique se a porta 1521 (ou a configurada) está acessível
Erro: "Autenticação falhou"
- ✅ Verifique nome de usuário e senha
- ✅ Confirme permissões do usuário no banco
- ✅ Para Oracle Cloud, inclua o domínio no usuário:
usuario@seu_dominio - ✅ Verifique se o usuário tem privilégios de SELECT em ALL_*
Erro: "Comando não permitido"
- ✅ O servidor só aceita comandos SELECT
- ✅ Não use UPDATE, DELETE, INSERT, ALTER, DROP, CREATE, etc.
- ✅ Verifique se não há comentários SQL na query
Erro: "COLUMNS requer filtro"
- ✅ Ao pesquisar colunas, sempre informe
TABLE_NAMEOUCOLUMN_NAME - ✅ Use
COLUMN_NAMEcom padrão LIKE para buscas parciais:"%id"
Pool desconecta constantemente
- ✅ Use
ORACLE_MAX_RECONNECT_ATTEMPTSeORACLE_RECONNECT_DELAY_MSpara tunar resiliência - ✅ Verifique conectividade entre o servidor e o Oracle Database
- ✅ Aumente timeouts se estiver em rede lenta
- ✅ Verifique firewall/ACLs entre o cliente e o banco
Lentidão em queries grandes
- ✅ Use filtros mais específicos em getDatabaseMetadata
- ✅ Limite a quantidade de dados com WHERE clauses
- ✅ Considere usar índices no banco de dados
- ✅ Verifique o EXPLAIN PLAN para queries complexas
Erro "not logged on" ou "connection lost"
- ✅ O servidor tentará reconectar automaticamente
- ✅ Verifique logs no console para detalhes
- ✅ Confirme se o Oracle Database não está em manutenção
- ✅ Verifique session timeout do banco
📊 Saída de Exemplo
Consultar Employees
{
"result": [
{
"EMP_ID": 101,
"EMP_NAME": "João Silva",
"EMAIL": "[email protected]",
"DEPARTMENT": "SALES",
"SALARY": 75000
},
{
"EMP_ID": 102,
"EMP_NAME": "Maria Costa",
"EMAIL": "[email protected]",
"DEPARTMENT": "IT",
"SALARY": 85000
}
]
}Obter Metadados de Colunas
{
"result": [
{
"OWNER": "HR",
"TABLE_NAME": "EMPLOYEES",
"COLUMN_NAME": "EMP_ID",
"DATA_TYPE": "NUMBER",
"DATA_LENGTH": 22,
"NULLABLE": "N",
"COLUMN_ID": 1
},
{
"OWNER": "HR",
"TABLE_NAME": "EMPLOYEES",
"COLUMN_NAME": "EMP_NAME",
"DATA_TYPE": "VARCHAR2",
"DATA_LENGTH": 255,
"NULLABLE": "N",
"COLUMN_ID": 2
}
]
}Listar Packages
{
"result": [
{
"OWNER": "HR",
"PACKAGE_NAME": "PKG_HR_UTILS",
"STATUS": "VALID",
"LAST_DDL_TIME": "2024-01-15 10:30:45"
},
{
"OWNER": "HR",
"PACKAGE_NAME": "PKG_REPORTS",
"STATUS": "VALID",
"LAST_DDL_TIME": "2024-01-10 14:20:00"
}
]
}Obter Código-Fonte de Package
{
"result": [
{
"owner": "HR",
"name": "PKG_HR_UTILS",
"type": "PACKAGE BODY",
"source": "CREATE OR REPLACE PACKAGE BODY PKG_HR_UTILS IS\n\n PROCEDURE hire_employee(p_name VARCHAR2, p_salary NUMBER) IS\n BEGIN\n INSERT INTO employees (emp_name, salary) VALUES (p_name, p_salary);\n COMMIT;\n END hire_employee;\n\nEND PKG_HR_UTILS;\n"
}
]
}🚦 Status de Compilação
- TypeScript: ✅ v4.5+
- Node.js: ✅ v16+
- Oracle Database: ✅ 11g+
- Oracle Cloud Database: ✅ Suportado
- MCP SDK: ✅ v1.15+
- oracledb (node-oracledb): ✅ v6.10+
📄 Licença
ISC
