damoxing-datasource-mcp
@damoxing/datasource-manager
중국어 문서: README.zh-CN.md
HTTP에 종속되지 않는 다중 데이터 소스 수명 주기 관리자입니다.
다음 기능을 제공합니다:
데이터 소스 설정 로딩
데이터 소스 상태 추적
jgbh호환성을 갖춘 일반 라우트 키 해석하트비트
풀 복구
연결 오류에 대한 일회성 재시도
정상 종료
핵심 관리자는 HTTP에 바인딩되지 않습니다. Express, 워커, CLI 또는 다른 Node.js 서비스 내에서 실행될 수 있습니다.
Oracle, OceanBase(Oracle/MySQL 모드), MySQL, DM, PostgreSQL, GaussDB/openGauss, Kingbase용 데이터베이스 어댑터가 포함되어 있습니다. 드라이버는 선택적 피어 종속성이며 해당 어댑터가 사용될 때만 로드됩니다.
어댑터 계약
어댑터 인스턴스는 다음을 노출해야 합니다:
{
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)은 선택 사항입니다.
Related MCP server: engineering-bridge
사용법
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),
});새로운 비즈니스 특화 코드에는 getByRouteKey()를 사용하세요:
const db = manager.getByRouteKey('tenant-a');getByJgbh()는 호환성 래퍼로 유지됩니다.
Codex용 MCP 서버
이 패키지는 stdio MCP 서버를 포함하여 Codex가 동일한 관리자 및 어댑터 계층을 통해 구성된 데이터 소스를 검사할 수 있도록 합니다:
npm run build
DAMOXING_MCP_CONFIG=/absolute/path/to/datasources.json node dist/cjs/mcp/server.js패키지 설치 후 bin 항목은 다음과 같습니다:
damoxing-datasource-mcpMCP 서버는 상태, 읽기 전용 쿼리, 테이블/루틴 메타데이터, 실행 계획 도구 및 MCP 전용 고정 물리적 세션을 노출합니다:
damoxing_open_sessiondamoxing_session_querydamoxing_session_execdamoxing_session_commitdamoxing_session_rollbackdamoxing_cancel_session_operationdamoxing_get_noticesdamoxing_get_audit_eventsdamoxing_close_session
동일한 sessionId를 전달하는 모든 작업은 동일한 임대 데이터베이스 연결을 사용하며 직렬화됩니다. PostgreSQL 호환 세션은 명시적 트랜잭션 내에서 실행됩니다. 종료 및 비정상 연결 정리는 임대 해제 전에 롤백됩니다. 손실된 고정 연결은 다른 연결에서 재시도되지 않습니다.
고정 세션은 기본적으로 읽기 전용입니다. 읽기/쓰기 세션을 열려면 DAMOXING_MCP_ALLOW_WRITE=true와 confirmWrite=true가 필요합니다. DAMOXING_MCP_PRODUCTION_DATASOURCES에 나열된 데이터 소스 ID는 DAMOXING_MCP_ALLOW_PRODUCTION_DEBUG=true가 설정되고 호출이 confirmProduction=true를 전달하지 않는 한 거부됩니다. 파괴적 SQL은 추가로 DAMOXING_MCP_ALLOW_DESTRUCTIVE=true와 confirmDestructive=true가 필요합니다.
세션 정책은 다음으로 제한될 수 있습니다:
DAMOXING_MCP_MAX_SESSIONS(기본값5)DAMOXING_MCP_MAX_SESSIONS_PER_DATASOURCE(기본값2)DAMOXING_MCP_SESSION_IDLE_TIMEOUT_MS(기본값300000)DAMOXING_MCP_SESSION_MAX_LIFETIME_MS(기본값1800000)DAMOXING_MCP_SESSION_CLEANUP_INTERVAL_MS(기본값30000)DAMOXING_MCP_AUDIT_MAX_EVENTS(기본값1000)
MCP 세션 레지스트리는 제한된 인메모리 감사 추적을 유지합니다. 감사 이벤트에는 작업, 결과, 데이터 소스/세션 식별자, 경과 시간, 행 수, SQL 종류, 정규화된 SQL 지문, 매개변수 개수/이름이 포함됩니다. SQL 텍스트와 매개변수 값은 절대 저장되지 않습니다. damoxing_get_audit_events를 사용하여 수정된 이벤트를 검색하세요.
고정 세션 관리자, 레지스트리, 타이머 및 예약 연결은 MCP 진입점에 의해 지연 생성됩니다. @damoxing/datasource-manager를 직접 가져오면 MCP SDK가 로드되거나 MCP 리소스가 생성되지 않습니다.
2026년 7월 15일 로컬 OrbStack 랩에서의 고정 세션 통합 결과:
데이터베이스 | 고정 연결 / 트랜잭션 | 세션 상태 | 알림 | 시간 초과 / 취소 |
PostgreSQL | 통과 | 임시 테이블 및 세션 변수 통과 | 통과 | 네이티브 |
openGauss | 통과 | 임시 테이블 및 세션 변수 통과 | 통과 | 네이티브 |
Oracle | 통과 | 안정적인 SID 및 | PostgreSQL NOTICE 의미 체계 사용 불가 |
|
DM | 통과 | 안정적인 세션 ID 및 전역 임시 테이블 통과 | 현재 드라이버에서 노출되지 않음 | 현재 |
Kingbase | 보류 중 | 로컬 컨테이너 데이터베이스 프로세스가 개발 라이선스 만료로 시작할 수 없음 | 확인되지 않음 | 확인되지 않음 |
npm run test:integration:session:pg, npm run test:integration:session:opengauss, npm run test:integration:session:oracle, npm run test:integration:session:dm을 실행하여 확인된 매트릭스를 반복하세요.
이 단계는 고정 세션 기반이며 완전한 저장 루틴 디버깅이 아닙니다. 구조화된 OUT/INOUT 값, 커서 핸들/페치, 루틴 프로파일링 및 네이티브 중단점은 여전히 로드맵 작업입니다.
리포지토리 스킬은 skills/damoxing-database-mcp에 있습니다.
상태 출력
getHealth()는 안정적이고 정리된 스키마를 반환합니다:
{
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
}
]
}데이터 소스 설정은 상태 출력에 절대 포함되지 않으므로 비밀번호와 연결 문자열이 노출되지 않습니다.
로깅
데이터 소스 오류는 두 번째 로거 인수로 구조화된 컨텍스트와 함께 기록됩니다:
{
datasourceId,
type,
jgbh,
jgbhList,
routeKeys,
status,
lastError,
error
}SQL 텍스트 로깅은 기본적으로 활성화되어 있습니다. SQL 매개변수 로깅은 프로덕션 비밀 유출을 방지하기 위해 기본적으로 비활성화되어 있습니다.
어댑터 옵션을 사용하여 매개변수 로깅을 제어하세요:
const adapterFactories = createDefaultAdapterFactories({
logger,
logSql: true,
logParams: 'redacted',
redactKeys: ['password', 'token', 'secret'],
redactValue: '[REDACTED]'
});logParams는 다음을 허용합니다:
false또는'off': SQL 매개변수를 기록하지 않음true또는'redacted': 민감한 키가 수정된 매개변수 기록'raw': 로컬 디버깅 전용으로 원시 매개변수 기록
정상 종료
shutdownSignals를 사용하여 프로세스가 신호를 수신할 때 모든 풀을 닫습니다:
const manager = new DataSourceManager({
shutdownSignals: ['SIGTERM', 'SIGINT'],
exitOnShutdownSignal: true,
adapterFactories,
config
});closeAll()은 하트비트 타이머를 중지하고, 종료 후크를 제거하고, 어댑터를 닫고, 데이터 소스를 closed로 표시합니다.
설정 형태
{
"strict_routing": true,
"default_datasource": "oracle_main",
"datasources": [
{
"id": "oracle_main",
"type": "oracle",
"jgbh_list": ["1001"],
"route_keys": ["tenant-a"],
"config": {}
}
]
}풀 거버넌스
데이터 소스 수준 또는 config.pool 아래에서 정규화된 풀 옵션을 사용하세요:
{
"id": "pg_main",
"type": "pg",
"pool": {
"minPoolSize": 1,
"maxPoolSize": 10,
"acquireTimeoutMs": 3000,
"connectTimeoutMs": 3000,
"idleTimeoutMs": 60000,
"maxLifetimeMs": 1800000,
"keepaliveMs": 30000
},
"config": {}
}관리자는 지원되는 옵션을 각 드라이버에 매핑하고 지원되지 않는 옵션을 데이터 소스 컨텍스트와 함께 기록합니다. minPoolSize > maxPoolSize와 같은 잘못된 값은 설정 빌드 중에 실패합니다.
applyPoolGovernance(type, config, pool)은 테스트 및 진단을 위해 내보내집니다.
메트릭
getMetrics()는 SQL 텍스트, 매개변수, 비밀번호 또는 연결 문자열 없이 카운터, 게이지 및 지연 시간 요약을 반환합니다:
const metrics = manager.getMetrics();메트릭은 현재 초기화, 하트비트, 복구, 쿼리 성공/실패, 연결 오류, 재시도 및 트랜잭션 연결 오류를 추적합니다.
런타임 거버넌스
데이터 소스는 런타임에 변경될 수 있습니다:
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()는 이전 풀을 닫기 전에 교체를 초기화하고 핑합니다. 교체 초기화가 실패하면 이전 데이터 소스가 활성 상태로 유지됩니다.
읽기/쓰기 그룹
그룹 라우팅은 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');읽기 전략은 round-robin, random, weighted, first-ready입니다. 비정상 읽기 복제본은 건너뜁니다.
설정 비밀
설정 값은 환경 변수 보간, 환경 참조, 비밀 해결자 후크 및 암호화된 값을 지원합니다:
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)"
}해결된 비밀은 상태 출력, 메트릭 출력, 구조화된 데이터 소스 오류 상태 및 관리자 로그에서 수정됩니다.
재시도 규칙
연결 유사 오류는 풀 복구 후 한 번 재시도될 수 있습니다.
트랜잭션은 자동으로 재생되지 않습니다. 트랜잭션이 연결 오류로 실패하면 관리자는 풀을 재구축하고 원래 오류를 다시 던집니다.
npm 패키징
이 패키지는 src/ 아래에 TypeScript로 작성되었으며 두 가지 모듈 형식으로 빌드됩니다:
CommonJS:
dist/cjs/index.jsESM:
dist/esm/index.mjs타입:
dist/types/index.d.ts
게시 전에 로컬에서 빌드하세요:
npm install
npm run release:checkESM 출력은 esbuild로 TypeScript에서 컴파일됩니다. 루트 및 어댑터 집계 가져오기는 데이터베이스 드라이버를 지연 로드하므로 패키지를 가져와도 oracledb, dmdb 또는 pg가 즉시 로드되지 않습니다.
내장 데이터베이스 드라이버는 선택적 피어 종속성으로 선언됩니다:
oracledb(Oracle용)mysql2(MySQL 및 두 OceanBase Oracle/MySQL 테넌트 모드용)dmdb(DM용)pg(PostgreSQL, GaussDB/openGauss 및 Kingbase용)
패키지 루트를 가져와도 이러한 드라이버가 즉시 로드되지 않습니다. 어댑터 클래스에 접근하거나 createDefaultAdapterFactories()를 통해 어댑터를 생성하면 해당 데이터 소스 유형에 필요한 드라이버만 로드됩니다.
semver, 레지스트리, 토큰, 출처 및 최종 게시 체크리스트 지침은 RELEASE.md를 참조하세요.
엔터프라이즈 데이터 소스 프레임워크 백로그 및 우선순위 순서는 ROADMAP.md를 참조하세요.
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