mcp-server-db2i 1.2.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -308
- package/dist/auth/authMiddleware.d.ts +66 -0
- package/dist/auth/authMiddleware.d.ts.map +1 -0
- package/dist/auth/authMiddleware.js +217 -0
- package/dist/auth/authMiddleware.js.map +1 -0
- package/dist/auth/index.d.ts +9 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +10 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/tokenManager.d.ts +114 -0
- package/dist/auth/tokenManager.d.ts.map +1 -0
- package/dist/auth/tokenManager.js +255 -0
- package/dist/auth/tokenManager.js.map +1 -0
- package/dist/auth/types.d.ts +103 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +10 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/config.d.ts +128 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +185 -0
- package/dist/config.js.map +1 -1
- package/dist/db/connection.d.ts +53 -3
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +154 -15
- package/dist/db/connection.js.map +1 -1
- package/dist/db/queries.d.ts +29 -6
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +35 -12
- package/dist/db/queries.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -42
- package/dist/index.js.map +1 -1
- package/dist/openapi.d.ts +49 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +634 -0
- package/dist/openapi.js.map +1 -0
- package/dist/server.d.ts +26 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +68 -22
- package/dist/server.js.map +1 -1
- package/dist/tools/metadata.d.ts +10 -0
- package/dist/tools/metadata.d.ts.map +1 -1
- package/dist/tools/metadata.js +10 -6
- package/dist/tools/metadata.js.map +1 -1
- package/dist/tools/query.d.ts +4 -0
- package/dist/tools/query.d.ts.map +1 -1
- package/dist/tools/query.js +5 -3
- package/dist/tools/query.js.map +1 -1
- package/dist/transports/http.d.ts +26 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +552 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/index.d.ts +8 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/transports/index.js +8 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/transports/sessionManager.d.ts +106 -0
- package/dist/transports/sessionManager.d.ts.map +1 -0
- package/dist/transports/sessionManager.js +260 -0
- package/dist/transports/sessionManager.js.map +1 -0
- package/package.json +9 -5
package/dist/index.js
CHANGED
|
@@ -4,67 +4,122 @@
|
|
|
4
4
|
*
|
|
5
5
|
* A Model Context Protocol server for querying and inspecting
|
|
6
6
|
* IBM DB2 for i (DB2i) databases using the JT400 JDBC driver.
|
|
7
|
+
*
|
|
8
|
+
* Supports two transport modes:
|
|
9
|
+
* - stdio (default): For CLI/IDE integration
|
|
10
|
+
* - http: For web/agent integration with token authentication
|
|
11
|
+
*
|
|
12
|
+
* Transport mode is controlled by MCP_TRANSPORT environment variable:
|
|
13
|
+
* - 'stdio' (default): Only stdio transport
|
|
14
|
+
* - 'http': Only HTTP transport
|
|
15
|
+
* - 'both': Both transports simultaneously
|
|
7
16
|
*/
|
|
8
17
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
|
-
import { loadConfig } from './config.js';
|
|
10
|
-
import { initializePool, testConnection } from './db/connection.js';
|
|
18
|
+
import { loadConfig, isHttpEnabled, isStdioEnabled, getTransportMode, getHttpConfig } from './config.js';
|
|
19
|
+
import { initializePool, testConnection, closeGlobalPool } from './db/connection.js';
|
|
11
20
|
import { logger, flushLogger } from './utils/logger.js';
|
|
12
21
|
import { getRateLimiter } from './utils/rateLimiter.js';
|
|
13
22
|
import { createServer, SERVER_NAME, SERVER_VERSION } from './server.js';
|
|
23
|
+
import { startHttpServer, shutdownHttpServer } from './transports/http.js';
|
|
14
24
|
/**
|
|
15
25
|
* Main entry point
|
|
16
26
|
*/
|
|
17
27
|
async function main() {
|
|
18
|
-
let
|
|
28
|
+
let stdioServer = null;
|
|
29
|
+
let httpServer = null;
|
|
19
30
|
/**
|
|
20
|
-
* Gracefully shutdown
|
|
31
|
+
* Gracefully shutdown all servers
|
|
21
32
|
*/
|
|
22
|
-
function shutdown(signal) {
|
|
33
|
+
async function shutdown(signal) {
|
|
23
34
|
logger.info(`Received ${signal}, shutting down...`);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
})
|
|
30
|
-
logger.error({ err: error }, 'Error closing MCP server');
|
|
31
|
-
flushLogger();
|
|
32
|
-
process.exit(1);
|
|
33
|
-
});
|
|
35
|
+
const shutdownPromises = [];
|
|
36
|
+
// Shutdown HTTP server if running
|
|
37
|
+
if (httpServer) {
|
|
38
|
+
shutdownPromises.push(shutdownHttpServer(httpServer).catch((err) => {
|
|
39
|
+
logger.error({ err }, 'Error shutting down HTTP server');
|
|
40
|
+
}));
|
|
34
41
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
// Shutdown stdio server if running
|
|
43
|
+
if (stdioServer) {
|
|
44
|
+
shutdownPromises.push(stdioServer.close().then(() => {
|
|
45
|
+
logger.info('Stdio MCP server closed');
|
|
46
|
+
}).catch((err) => {
|
|
47
|
+
logger.error({ err }, 'Error closing stdio MCP server');
|
|
48
|
+
}));
|
|
38
49
|
}
|
|
50
|
+
await Promise.all(shutdownPromises);
|
|
51
|
+
// Close global DB pool (used by stdio transport)
|
|
52
|
+
await closeGlobalPool();
|
|
53
|
+
flushLogger();
|
|
54
|
+
process.exit(0);
|
|
39
55
|
}
|
|
40
56
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const config = loadConfig();
|
|
44
|
-
logger.debug({ hostname: config.hostname, port: config.port }, 'Configuration loaded');
|
|
45
|
-
// Initialize database connection pool
|
|
46
|
-
initializePool(config);
|
|
47
|
-
logger.debug('Database connection pool initialized');
|
|
48
|
-
// Test the connection
|
|
49
|
-
const connected = await testConnection();
|
|
50
|
-
if (!connected) {
|
|
51
|
-
logger.warn('Could not verify database connection. The server will start but queries may fail.');
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
logger.info('Database connection verified');
|
|
55
|
-
}
|
|
57
|
+
const transportMode = getTransportMode();
|
|
58
|
+
logger.info({ transport: transportMode }, 'Starting MCP server...');
|
|
56
59
|
// Initialize rate limiter (logs its own config)
|
|
57
60
|
getRateLimiter();
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
// Check which transports are enabled
|
|
62
|
+
const stdioEnabled = isStdioEnabled();
|
|
63
|
+
const httpEnabled = isHttpEnabled();
|
|
64
|
+
// For stdio mode, we need DB config from environment
|
|
65
|
+
if (stdioEnabled) {
|
|
66
|
+
// Load configuration from environment variables
|
|
67
|
+
const config = loadConfig();
|
|
68
|
+
logger.debug({ hostname: config.hostname, port: config.port }, 'Configuration loaded for stdio');
|
|
69
|
+
// Initialize global database connection pool for stdio
|
|
70
|
+
initializePool(config);
|
|
71
|
+
logger.debug('Global database connection pool initialized');
|
|
72
|
+
// Test the connection
|
|
73
|
+
const connected = await testConnection();
|
|
74
|
+
if (!connected) {
|
|
75
|
+
logger.warn('Could not verify database connection. The server will start but queries may fail.');
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
logger.info('Database connection verified');
|
|
79
|
+
}
|
|
80
|
+
// Create and connect stdio MCP server
|
|
81
|
+
stdioServer = createServer();
|
|
82
|
+
const transport = new StdioServerTransport();
|
|
83
|
+
await stdioServer.connect(transport);
|
|
84
|
+
logger.info({ name: SERVER_NAME, version: SERVER_VERSION }, 'MCP server connected via stdio transport');
|
|
85
|
+
}
|
|
86
|
+
// Start HTTP server if enabled
|
|
87
|
+
// Note: getHttpConfig() is called here (not at startup) to avoid validating
|
|
88
|
+
// HTTP-specific settings when only stdio transport is being used
|
|
89
|
+
if (httpEnabled) {
|
|
90
|
+
const httpConfig = getHttpConfig();
|
|
91
|
+
logger.info({
|
|
92
|
+
port: httpConfig.port,
|
|
93
|
+
host: httpConfig.host,
|
|
94
|
+
sessionMode: httpConfig.sessionMode,
|
|
95
|
+
tlsEnabled: httpConfig.tls.enabled,
|
|
96
|
+
}, 'Starting HTTP transport...');
|
|
97
|
+
httpServer = await startHttpServer();
|
|
98
|
+
logger.info({ name: SERVER_NAME, version: SERVER_VERSION }, 'MCP server HTTP transport started');
|
|
99
|
+
}
|
|
100
|
+
// Log final status
|
|
101
|
+
if (stdioEnabled && httpEnabled) {
|
|
102
|
+
logger.info('MCP server running with both stdio and HTTP transports');
|
|
103
|
+
}
|
|
104
|
+
else if (stdioEnabled) {
|
|
105
|
+
logger.info('MCP server running with stdio transport only');
|
|
106
|
+
}
|
|
107
|
+
else if (httpEnabled) {
|
|
108
|
+
logger.info('MCP server running with HTTP transport only');
|
|
109
|
+
}
|
|
65
110
|
// Handle shutdown gracefully
|
|
66
|
-
process.on('SIGINT', () =>
|
|
67
|
-
|
|
111
|
+
process.on('SIGINT', () => {
|
|
112
|
+
shutdown('SIGINT').catch((err) => {
|
|
113
|
+
logger.error({ err }, 'Error during SIGINT shutdown');
|
|
114
|
+
process.exit(1);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
process.on('SIGTERM', () => {
|
|
118
|
+
shutdown('SIGTERM').catch((err) => {
|
|
119
|
+
logger.error({ err }, 'Error during SIGTERM shutdown');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
68
123
|
}
|
|
69
124
|
catch (error) {
|
|
70
125
|
logger.fatal({ err: error }, 'Failed to start MCP server');
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI 3.1 Specification for IBM DB2i MCP Server HTTP Transport
|
|
3
|
+
*
|
|
4
|
+
* Provides machine-readable API documentation for:
|
|
5
|
+
* - Authentication endpoint (/auth)
|
|
6
|
+
* - Health check endpoint (/health)
|
|
7
|
+
* - MCP protocol endpoints (/mcp)
|
|
8
|
+
*
|
|
9
|
+
* Can be imported into Postman, Insomnia, or other API clients.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* OpenAPI 3.1 specification type
|
|
13
|
+
*/
|
|
14
|
+
export interface OpenApiSpec {
|
|
15
|
+
openapi: string;
|
|
16
|
+
info: {
|
|
17
|
+
title: string;
|
|
18
|
+
version: string;
|
|
19
|
+
description: string;
|
|
20
|
+
license?: {
|
|
21
|
+
name: string;
|
|
22
|
+
url: string;
|
|
23
|
+
};
|
|
24
|
+
contact?: {
|
|
25
|
+
url: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
servers?: Array<{
|
|
29
|
+
url: string;
|
|
30
|
+
description: string;
|
|
31
|
+
}>;
|
|
32
|
+
tags?: Array<{
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
}>;
|
|
36
|
+
paths: Record<string, unknown>;
|
|
37
|
+
components?: {
|
|
38
|
+
securitySchemes?: Record<string, unknown>;
|
|
39
|
+
schemas?: Record<string, unknown>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Generate the OpenAPI specification
|
|
44
|
+
*
|
|
45
|
+
* @param baseUrl - Optional base URL for the server (defaults to relative paths)
|
|
46
|
+
* @returns OpenAPI 3.1 specification object
|
|
47
|
+
*/
|
|
48
|
+
export declare function getOpenApiSpec(baseUrl?: string): OpenApiSpec;
|
|
49
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;QACxC,OAAO,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE;QACX,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAgnB5D"}
|