damoxing-datasource-mcp
@damoxing/datasource-manager
Documentación en chino: README.zh-CN.md
Gestor de ciclo de vida de múltiples fuentes de datos independiente de HTTP.
Posee:
Carga de configuración de fuentes de datos
Seguimiento del estado de las fuentes de datos
Resolución genérica de clave de ruta, con compatibilidad
jgbhHeartbeat
Recuperación de pool
Reintento único para errores de conexión
Apagado ordenado
El gestor principal no está vinculado a HTTP. Puede ejecutarse dentro de Express, un worker, una CLI u otro servicio Node.js.
Se incluyen adaptadores de base de datos para Oracle, OceanBase (modo Oracle / MySQL), MySQL, DM, PostgreSQL, GaussDB/openGauss y Kingbase. Los controladores son dependencias opcionales entre pares y se cargan solo cuando se utiliza el adaptador correspondiente.
Contrato del Adaptador
Una instancia de adaptador debe exponer:
{
isOracle: Boolean,
adapterType: String,
initialize: async () => {},
close: async () => {},
all: async (sql, params) => [],
get: async (sql, params) => row,
run: async (sql, params) => result,
exec: async (sql) => {},
transaction: async (work) => result
}withConnection(callback) es opcional.
Related MCP server: engineering-bridge
Uso
CommonJS:
const {
DataSourceManager,
createDefaultAdapterFactories
} = require('@damoxing/datasource-manager');
const manager = new DataSourceManager({
config,
logger,
shutdownSignals: ['SIGTERM'],
adapterFactories: createDefaultAdapterFactories(logger),
});
await manager.initialize();
const db = manager.getByJgbh('1001');
const row = await db.get('SELECT 1 AS health_check');
await manager.closeAll();ESM:
import {
DataSourceManager,
createDefaultAdapterFactories
} from '@damoxing/datasource-manager';
const manager = new DataSourceManager({
config,
logger,
adapterFactories: createDefaultAdapterFactories(logger),
});Use getByRouteKey() para código nuevo no específico de negocio:
const db = manager.getByRouteKey('tenant-a');getByJgbh() permanece como envoltorio de compatibilidad.
Servidor MCP para Codex
Este paquete incluye un servidor MCP stdio para que Codex pueda inspeccionar las fuentes de datos configuradas a través de la misma capa de gestor y adaptador:
npm run build
DAMOXING_MCP_CONFIG=/absolute/path/to/datasources.json node dist/cjs/mcp/server.jsDespués de la instalación del paquete, la entrada binaria es:
damoxing-datasource-mcpEl servidor MCP expone herramientas de salud, consulta de solo lectura, metadatos de tablas/rutinas, plan de explicación y sesiones físicas fijas solo para MCP:
damoxing_open_sessiondamoxing_session_querydamoxing_session_execdamoxing_session_commitdamoxing_session_rollbackdamoxing_cancel_session_operationdamoxing_get_noticesdamoxing_get_audit_eventsdamoxing_close_session
Todas las operaciones que llevan el mismo sessionId utilizan la misma conexión de base de datos arrendada y están serializadas. Las sesiones compatibles con PostgreSQL se ejecutan dentro de una transacción explícita; el cierre y la limpieza de conexión anormal revierten antes de liberar el arrendamiento. Una conexión fija perdida nunca se reintenta en otra conexión.
Las sesiones fijas son de solo lectura por defecto. Abrir una sesión de lectura/escritura requiere DAMOXING_MCP_ALLOW_WRITE=true y confirmWrite=true. Los identificadores de fuente de datos listados en DAMOXING_MCP_PRODUCTION_DATASOURCES son denegados a menos que DAMOXING_MCP_ALLOW_PRODUCTION_DEBUG=true esté configurado y la llamada pase confirmProduction=true. El SQL destructivo adicionalmente requiere DAMOXING_MCP_ALLOW_DESTRUCTIVE=true y confirmDestructive=true.
La política de sesión se puede acotar con:
DAMOXING_MCP_MAX_SESSIONS(por defecto5)DAMOXING_MCP_MAX_SESSIONS_PER_DATASOURCE(por defecto2)DAMOXING_MCP_SESSION_IDLE_TIMEOUT_MS(por defecto300000)DAMOXING_MCP_SESSION_MAX_LIFETIME_MS(por defecto1800000)DAMOXING_MCP_SESSION_CLEANUP_INTERVAL_MS(por defecto30000)DAMOXING_MCP_AUDIT_MAX_EVENTS(por defecto1000)
El registro de sesiones MCP mantiene un rastro de auditoría en memoria acotado. Los eventos de auditoría contienen acción, resultado, identificadores de fuente de datos/sesión, tiempo transcurrido, recuentos de filas, tipo de SQL, una huella digital SQL normalizada y recuentos/nombres de parámetros. El texto SQL y los valores de los parámetros nunca se almacenan. Use damoxing_get_audit_events para recuperar los eventos censurados.
El gestor de sesiones fijas, el registro, el temporizador y las conexiones reservadas se crean de forma diferida por el punto de entrada MCP. Importar @damoxing/datasource-manager directamente no carga el SDK MCP ni crea recursos MCP.
Resultados de la integración de sesiones fijas del laboratorio local OrbStack del 15 de julio de 2026:
Base de datos | Conexión fija / transacción | Estado de la sesión | Notificaciones | Tiempo de espera / cancelación |
PostgreSQL | Pasado | Tablas temporales y variables de sesión pasadas | Pasado |
|
openGauss | Pasado | Tablas temporales y variables de sesión pasadas | Pasado |
|
Oracle | Pasado | SID estable y | Semántica de NOTICE de PostgreSQL no disponible |
|
DM | Pasado | ID de sesión estable y tabla temporal global pasada | No expuesto por el controlador actual | El controlador |
Kingbase | Pendiente | El proceso de la base de datos del contenedor local no puede iniciar porque su licencia de desarrollo ha expirado | No verificado | No verificado |
Ejecute npm run test:integration:session:pg, npm run test:integration:session:opengauss, npm run test:integration:session:oracle y npm run test:integration:session:dm para repetir la matriz verificada.
Esta fase es la base de sesiones fijas, no la depuración completa de rutinas almacenadas. Los valores estructurados OUT/INOUT, los manejadores de cursor/obtención, la creación de perfiles de rutinas y los puntos de interrupción nativos siguen siendo trabajo pendiente.
La habilidad del repositorio se encuentra en skills/damoxing-database-mcp.
Salida de Salud
getHealth() devuelve un esquema estable y sanitizado:
{
generatedAt,
initialized,
strictRouting,
defaultDatasourceId,
routeCount,
heartbeat: {
enabled,
running,
intervalMs
},
shutdownHooks: {
installed,
signals
},
summary: {
total,
ready,
failed,
unhealthy,
byStatus: {
configured,
initializing,
ready,
unhealthy,
failed,
recovering,
closed
}
},
datasources: [
{
id,
type,
status,
jgbhCount,
routeKeyCount,
isDefault,
lastHeartbeatAt,
lastReadyAt,
lastRecoverAt,
lastStatusChangeAt,
lastError
}
]
}La configuración de la fuente de datos nunca se incluye en la salida de salud, por lo que las contraseñas y las cadenas de conexión no se exponen.
Registro
Los errores de fuente de datos se registran con contexto estructurado como segundo argumento del registrador:
{
datasourceId,
type,
jgbh,
jgbhList,
routeKeys,
status,
lastError,
error
}El registro de texto SQL está habilitado por defecto. El registro de parámetros SQL está deshabilitado por defecto para evitar filtrar secretos de producción.
Use las opciones del adaptador para controlar el registro de parámetros:
const adapterFactories = createDefaultAdapterFactories({
logger,
logSql: true,
logParams: 'redacted',
redactKeys: ['password', 'token', 'secret'],
redactValue: '[REDACTED]'
});logParams acepta:
falseo'off': no registrar parámetros SQLtrueo'redacted': registrar parámetros con claves sensibles censuradas'raw': registrar parámetros sin procesar solo para depuración local
Apagado Ordenado
Use shutdownSignals para cerrar todos los pools cuando el proceso recibe una señal:
const manager = new DataSourceManager({
shutdownSignals: ['SIGTERM', 'SIGINT'],
exitOnShutdownSignal: true,
adapterFactories,
config
});closeAll() detiene los temporizadores de heartbeat, elimina los ganchos de apagado, cierra los adaptadores y marca las fuentes de datos como closed.
Forma de la Configuración
{
"strict_routing": true,
"default_datasource": "oracle_main",
"datasources": [
{
"id": "oracle_main",
"type": "oracle",
"jgbh_list": ["1001"],
"route_keys": ["tenant-a"],
"config": {}
}
]
}Gobierno del Pool
Use opciones de pool normalizadas a nivel de fuente de datos o bajo config.pool:
{
"id": "pg_main",
"type": "pg",
"pool": {
"minPoolSize": 1,
"maxPoolSize": 10,
"acquireTimeoutMs": 3000,
"connectTimeoutMs": 3000,
"idleTimeoutMs": 60000,
"maxLifetimeMs": 1800000,
"keepaliveMs": 30000
},
"config": {}
}El gestor asigna las opciones admitidas a cada controlador y registra las opciones no admitidas con contexto de fuente de datos. Los valores no válidos, como minPoolSize > maxPoolSize, fallan durante la construcción de la configuración.
applyPoolGovernance(type, config, pool) se exporta para pruebas y diagnósticos.
Métricas
getMetrics() devuelve contadores, medidores y resúmenes de latencia sin texto SQL, parámetros, contraseñas ni cadenas de conexión:
const metrics = manager.getMetrics();Las métricas actualmente rastrean inicialización, heartbeat, recuperación, éxito/fracaso de consultas, errores de conexión, reintentos y errores de conexión de transacciones.
Gobierno en Tiempo de Ejecución
Las fuentes de datos se pueden cambiar en tiempo de ejecución:
await manager.addDatasource({ id: 'tenant_a', type: 'pg', route_keys: ['TENANT_A'], config: {} });
await manager.updateDatasource('tenant_a', { id: 'tenant_a', type: 'pg', route_keys: ['TENANT_A'], config: {} });
await manager.removeDatasource('tenant_a');
await manager.reloadConfig(nextConfig);updateDatasource() inicializa y hace ping al reemplazo antes de cerrar el pool antiguo. Si la inicialización del reemplazo falla, la fuente de datos antigua permanece activa.
Grupos de Lectura/Escritura
El enrutamiento de grupos es independiente de HTTP:
{
"groups": {
"tenant_a": {
"write": "tenant_a_master",
"read": [
"tenant_a_read_1",
{ "id": "tenant_a_read_2", "weight": 2 }
],
"strategy": "round-robin",
"fallbackToWrite": true
}
}
}const readDb = manager.getReadHandle('tenant_a');
const writeDb = manager.getWriteHandle('tenant_a');Las estrategias de lectura son round-robin, random, weighted y first-ready. Las réplicas de lectura no saludables se omiten.
Secretos de Configuración
Los valores de configuración admiten interpolación de entorno, referencias de entorno, ganchos de resolución de secretos y valores cifrados:
const manager = new DataSourceManager({
env: process.env,
secretResolver: async key => loadSecret(key),
decryptor: async value => decrypt(value),
config
});{
"password": "env:DB_PASSWORD",
"token": "secret:database/token",
"connectString": "postgres://app:${DB_PASSWORD}@localhost/db",
"encrypted": "ENC(ciphertext)"
}Los secretos resueltos se censuran de la salida de salud, la salida de métricas, el estado de error estructurado de la fuente de datos y los registros del gestor.
Regla de Reintento
Los errores similares a conexión pueden reintentarse una vez después de la recuperación del pool.
Las transacciones no se reproducen automáticamente. Si una transacción falla con un error de conexión, el gestor reconstruye el pool y relanza el error original.
Empaquetado npm
Este paquete está escrito en TypeScript bajo src/ y compila ambos formatos de módulo:
CommonJS:
dist/cjs/index.jsESM:
dist/esm/index.mjsTipos:
dist/types/index.d.ts
Compile localmente antes de publicar:
npm install
npm run release:checkLa salida ESM se compila desde TypeScript con esbuild. Las importaciones agregadas de raíz y adaptador mantienen los controladores de base de datos diferidos, por lo que importar el paquete no carga inmediatamente oracledb, dmdb o pg.
Los controladores de base de datos integrados se declaran como dependencias opcionales entre pares:
oracledbpara Oraclemysql2para MySQL y ambos modos de inquilino OceanBase Oracle/MySQLdmdbpara DMpgpara PostgreSQL, GaussDB/openGauss y Kingbase
Importar la raíz del paquete no carga inmediatamente estos controladores. Acceder a las clases de adaptador o crear un adaptador a través de createDefaultAdapterFactories() carga solo el controlador necesario para ese tipo de fuente de datos.
Consulte RELEASE.md para obtener orientación sobre semver, registro, token, procedencia y lista de verificación de publicación final.
Consulte ROADMAP.md para conocer el backlog del marco de fuentes de datos empresariales y el orden de prioridad.
This server cannot be deployed
Maintenance
Related MCP Connectors
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Guarded MCP server for agent-readable business truth, provenance, readiness, and discovery.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Read-only MCP server for The Quiet Protocol's engines, benchmarks, proof, and business data.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA read-only MCP server for querying telemetry data from configurable backends. Provides tools to list sources, describe schemas, run bounded queries, and compute aggregates.MIT
- AlicenseNot gradedqualityAmaintenanceA local STDIO MCP server that bridges MCP clients to the Codex CLI by sending instructions to a configured workspace, exposing task run, status, and result tools with a read-only sandbox and no remote transport.133MIT
- FlicenseNot gradedqualityCmaintenanceEnables querying enterprise records and retention policies from any MCP client over stdio, with read-only tools for searching records, fetching retention verdicts, identifying archival candidates, summarizing departments, forecasting retentions, and viewing audit history.-
- AlicenseAqualityCmaintenanceEnables MCP clients such as Codex to safely inspect a MySQL database over stdio by listing tables, describing schemas and indexes, and running only validated single read-only SELECT/CTE queries plus JSON EXPLAIN plans. Queries execute inside read-only transactions with strict AST-based rejection of writes, multi-statements, and other risky operations, and results come back as structured JSON.666 npmMIT