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: telemetry-mcp
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 installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityFmaintenanceRead-only MCP server for SQL databases (SQL Server, Postgres, SQLite) with multi-server support and three-layer safety using AST validation and linting.MIT
- Alicense-qualityAmaintenanceA 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
- FlicenseAqualityCmaintenanceLocal stdio MCP server for read-only Microsoft SQL Server access through Python and pyodbc, providing test connection, list tables, describe table, and query tools.4
- Alicense-qualityAmaintenanceMCP server that connects to SQL databases (SQLite, PostgreSQL, MSSQL, MySQL) and provides tools to run read-only queries, list schemas/tables, and manage connections via stdio transport.Apache 2.0
Related MCP Connectors
Hosted MCP server for agent governance: MCP config audits, injection scans, scope-policy checks.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
MCP server for managing Prisma Postgres.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/xiaochen201807/damoxing-datasource-manager'
If you have feedback or need assistance with the MCP directory API, please join our Discord server