Estrutura inicial, ambiente IA

This commit is contained in:
victor
2026-05-14 09:54:24 -03:00
commit 48095a3c64
49 changed files with 4596 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
# Single connection
ORACLE_CONNECTION_NAME=SUPERUS_PRODUCAO
ORACLE_USER=verdemar
ORACLE_PASSWORD=preencha_aqui
ORACLE_CONNECT_STRING=oracle-scan1.superverdemar.local:1521/SMARTSRV
# Optional multi-connection JSON
# ORACLE_CONNECTIONS_JSON={"SUPERUS_PRODUCAO":{"user":"verdemar","password":"preencha_aqui","connectString":"oracle-scan1.superverdemar.local:1521/SMARTSRV"},"SUPERUS_TESTE":{"user":"verdemar","password":"preencha_aqui","connectString":"oracleteste.superverdemar.local:1521/SMARTTST"}}
# ORACLE_DEFAULT_CONNECTION=SUPERUS_PRODUCAO
# ORACLE_BACKEND=auto
# ORACLE_SQLCL_PATH=/caminho/para/sqlcl/bin/sql
# Execution safety
ORACLE_CALL_TIMEOUT_MS=15000
ORACLE_SQLCL_TIMEOUT_MS=20000
ORACLE_DEFAULT_MAX_ROWS=200
ORACLE_HARD_MAX_ROWS=1000
ORACLE_FETCH_ARRAY_SIZE=100
ORACLE_POOL_MIN=0
ORACLE_POOL_MAX=4
ORACLE_POOL_INCREMENT=1
ORACLE_POOL_TIMEOUT=60
ORACLE_QUEUE_TIMEOUT_MS=5000
ORACLE_STMT_CACHE_SIZE=30
+2
View File
@@ -0,0 +1,2 @@
node_modules/
.env
+124
View File
@@ -0,0 +1,124 @@
# MCP Oracle Custom
Servidor MCP local para Oracle com foco em estabilidade:
- pool de conexoes reutilizavel
- timeout por chamada
- limite padrao e limite rigido de linhas
- execucao apenas de consultas de leitura
- fallback automatico para SQLcl quando o driver Thin do node-oracledb nao suporta o verificador de senha da conta
## Arquivos
- `server.mjs`: servidor MCP via stdio
- `cli.mjs`: entrypoint Node executavel e cross-platform
- `run-mcp.sh`: bootstrap local que encontra `node`, instala dependencias quando necessario e sobe o servidor
- `.env.example`: exemplo de configuracao das conexoes
## Configuracao
1. Copie `.env.example` para `.env`
2. Preencha usuario, senha e connect string
3. Ajuste limites e timeout se necessario
Alternativas para configuracao:
- voce pode passar um arquivo externo com `--env-file /caminho/para/.env`
- voce pode definir as variaveis diretamente no ambiente do processo MCP
- na ausencia de `--env-file`, o servidor procura `.env` no diretorio atual, em diretorios pais, em `mcp-oracle-custom/.env` a partir do diretorio atual e, por fim, na pasta do pacote
Variaveis opcionais de backend:
- `ORACLE_BACKEND=auto`: tenta `node-oracledb` primeiro e cai para SQLcl quando necessario
- `ORACLE_BACKEND=oracledb`: forca uso apenas do driver Node
- `ORACLE_BACKEND=sqlcl`: forca uso apenas do SQLcl
- `ORACLE_SQLCL_PATH`: caminho explicito para o executavel `sql`
- `ORACLE_SQLCL_TIMEOUT_MS`: timeout do fallback SQLcl
Se `ORACLE_SQLCL_PATH` nao for informado, o servidor tenta localizar o SQLcl automaticamente em instalacoes comuns do VS Code sob o diretorio do usuario e em caminhos padrao do sistema.
## Ferramentas expostas
- `list_connections`: lista as conexoes configuradas
- `test_connection`: testa a conexao com o banco
- `run_query`: executa `SELECT` ou `WITH` com binds opcionais em JSON
- `reset_pools`: fecha todos os pools mantidos pelo servidor
## Observacoes
- Este MCP bloqueia DDL e DML por seguranca
- O servidor pode carregar o `.env` da pasta atual, da propria pasta do pacote ou de um arquivo informado em `--env-file`
- O retorno da consulta vem em JSON com colunas, linhas, truncamento e conexao usada
- Quando o fallback SQLcl estiver ativo, `bindsJson` nao e suportado
- O parser do fallback SQLcl normaliza numeros retornados com virgula decimal para manter o JSON valido
- Se quiser ampliar para metadata, DDL gerado ou chamadas especificas, da para adicionar novas ferramentas depois
## Uso no workspace
O arquivo `.vscode/mcp.json` deste workspace pode apontar diretamente para `./mcp-oracle-custom/run-mcp.sh` via `bash`.
Depois de preencher o `.env`, recarregue o VS Code ou o catalogo de MCPs para o servidor aparecer.
Esse bootstrap local faz o seguinte:
- procura um `node` no PATH e, se nao encontrar, tenta usar o Node embutido do VS Code neste ambiente Linux
- evita depender de caminhos fixos de um usuario especifico para localizar o Node embutido do VS Code
- verifica se as dependencias do pacote estao presentes
- executa `npm install` automaticamente quando as dependencias estiverem ausentes ou desatualizadas
- exibe mensagens claras quando `node` ou `npm` nao existirem no ambiente
## Instalacao cross-platform
Para usar no Windows e no Linux sem depender do `run-mcp.sh`, instale o pacote com npm para gerar o comando executavel `mcp-oracle-custom`:
```bash
npm install -g .
```
Depois disso, o comando abaixo fica disponivel no sistema:
```bash
mcp-oracle-custom --help
```
No Windows, o npm cria automaticamente o shim executavel correspondente.
No Linux, o comando e exposto como executavel com shebang Node.
Quando o comando for executado a partir do workspace do repositorio, o servidor encontra automaticamente `mcp-oracle-custom/.env`.
No bootstrap local via `run-mcp.sh`, nao e necessario instalar o pacote globalmente. O requisito e ter `node` disponivel para executar o servidor e `npm` disponivel quando for necessario instalar dependencias.
## Exemplo de configuracao em clientes MCP
Exemplo generico para VS Code, Copilot ou Claude Desktop usando o executavel do pacote:
```json
{
"mcpServers": {
"oracle-davinti": {
"command": "mcp-oracle-custom"
}
}
}
```
Se preferir, ainda e possivel informar `--env-file` explicitamente. O `cli.mjs` foi adicionado para permitir distribuicao e instalacao sem depender de shell Bash.
## Exemplo de bootstrap local no workspace
Exemplo para VS Code no Linux usando o launcher do repositorio:
```json
{
"servers": {
"oracle-davinti": {
"type": "stdio",
"command": "bash",
"args": [
"./mcp-oracle-custom/run-mcp.sh"
]
}
}
}
```
Se `node` nao existir, o bootstrap encerra informando isso explicitamente.
Se as dependencias ainda nao estiverem instaladas e `npm` nao existir, o bootstrap tambem encerra com mensagem clara explicando o que falta.
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
function printHelp() {
const lines = [
'mcp-oracle-custom',
'',
'Servidor MCP Oracle via stdio.',
'',
'Uso:',
' mcp-oracle-custom',
' mcp-oracle-custom --env-file /caminho/para/.env',
' mcp-oracle-custom --help',
' mcp-oracle-custom --version',
'',
'Opcoes:',
' --env-file <arquivo> Informa um arquivo .env externo para o servidor.',
' --help Exibe esta ajuda.',
' --version Exibe a versao do pacote.'
];
process.stdout.write(lines.join('\n') + '\n');
}
function fail(message) {
process.stderr.write(String(message || 'Falha ao iniciar o MCP Oracle.') + '\n');
process.exit(1);
}
function resolveCliEnvFile(value) {
const normalized = String(value || '').trim();
if (!normalized) {
return '';
}
return path.resolve(process.cwd(), normalized);
}
const args = process.argv.slice(2);
for (let index = 0; index < args.length; index += 1) {
const current = args[index];
if (current == '--help' || current == '-h') {
printHelp();
process.exit(0);
}
if (current == '--version' || current == '-v') {
process.stdout.write(String(packageJson.version || '0.0.0') + '\n');
process.exit(0);
}
if (current == '--env-file') {
const nextValue = args[index + 1];
if (!nextValue) {
fail('Informe o caminho apos --env-file.');
}
process.env.MCP_ORACLE_ENV_FILE = resolveCliEnvFile(nextValue);
index += 1;
continue;
}
fail('Opcao nao suportada: ' + current);
}
await import('./server.mjs');
+1151
View File
File diff suppressed because it is too large Load Diff
+32
View File
@@ -0,0 +1,32 @@
{
"name": "mcp-oracle-custom",
"version": "1.0.0",
"description": "Custom MCP server for Oracle with pool, timeout and row limits.",
"main": "server.mjs",
"bin": {
"mcp-oracle-custom": "./cli.mjs"
},
"files": [
"cli.mjs",
"server.mjs",
"run-mcp.sh",
"README.md",
".env.example"
],
"scripts": {
"start": "node ./cli.mjs",
"pack": "npm pack"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"engines": {
"node": ">=18"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.29.0",
"oracledb": "^6.10.0",
"zod": "^4.3.6"
}
}
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
NODE_BIN=""
NPM_BIN=""
log_error() {
echo "$1" >&2
}
find_node() {
if command -v node >/dev/null 2>&1; then
NODE_BIN="$(command -v node)"
return 0
fi
find_vscode_node_bin && return 0
return 1
}
find_vscode_node_bin() {
local base_dirs=()
local candidate=""
if [[ -n "${VSCODE_AGENT_FOLDER:-}" ]]; then
base_dirs+=("$VSCODE_AGENT_FOLDER")
fi
if [[ -n "${HOME:-}" ]]; then
base_dirs+=(
"$HOME/.vscode-server"
"$HOME/.vscode-server-insiders"
)
fi
for base_dir in "${base_dirs[@]}"; do
[[ -d "$base_dir/bin" ]] || continue
for candidate in "$base_dir"/bin/*/node; do
if [[ -x "$candidate" ]]; then
NODE_BIN="$candidate"
return 0
fi
done
done
return 1
}
find_npm() {
if command -v npm >/dev/null 2>&1; then
NPM_BIN="$(command -v npm)"
return 0
fi
return 1
}
needs_install() {
[[ ! -d "$SCRIPT_DIR/node_modules" ]] && return 0
[[ ! -d "$SCRIPT_DIR/node_modules/@modelcontextprotocol/sdk" ]] && return 0
[[ ! -d "$SCRIPT_DIR/node_modules/oracledb" ]] && return 0
[[ ! -d "$SCRIPT_DIR/node_modules/zod" ]] && return 0
return 1
}
install_dependencies() {
if ! find_npm; then
log_error "npm nao encontrado. O bootstrap local do MCP Oracle precisa do npm para instalar as dependencias em $SCRIPT_DIR."
log_error "Instale Node.js com npm ou rode a instalacao manualmente nessa pasta antes de iniciar o MCP."
exit 1
fi
log_error "Dependencias do MCP Oracle ausentes ou desatualizadas. Executando npm install em $SCRIPT_DIR..."
(
cd "$SCRIPT_DIR"
"$NPM_BIN" install --no-fund --no-audit
)
}
if ! find_node; then
log_error "Node nao encontrado. O bootstrap local do MCP Oracle precisa do Node.js para iniciar o servidor."
log_error "Instale o Node.js no ambiente ou ajuste o PATH para um binario node valido."
exit 1
fi
if needs_install; then
install_dependencies
fi
exec "$NODE_BIN" "$SCRIPT_DIR/server.mjs"
File diff suppressed because it is too large Load Diff