mcp-server-db2i 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ström Capital
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,252 @@
1
+ # mcp-server-db2i
2
+
3
+ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for IBM DB2 for i (DB2i). This server enables AI assistants like Claude and Cursor to query and inspect IBM i databases using the JT400 JDBC driver.
4
+
5
+ ## Features
6
+
7
+ - **Read-only SQL queries** - Execute SELECT statements safely with automatic result limiting
8
+ - **Schema inspection** - List all schemas/libraries with optional filtering
9
+ - **Table metadata** - List tables, describe columns, view indexes and constraints
10
+ - **View inspection** - List and explore database views
11
+ - **Secure by design** - Only SELECT queries allowed, credentials via environment variables
12
+ - **Docker support** - Run as a container for easy deployment
13
+
14
+ ## Available Tools
15
+
16
+ | Tool | Description |
17
+ |------|-------------|
18
+ | `execute_query` | Execute read-only SELECT queries |
19
+ | `list_schemas` | List schemas/libraries (with optional filter) |
20
+ | `list_tables` | List tables in a schema (with optional filter) |
21
+ | `describe_table` | Get detailed column information |
22
+ | `list_views` | List views in a schema (with optional filter) |
23
+ | `list_indexes` | List indexes for a table |
24
+ | `get_table_constraints` | Get primary keys, foreign keys, unique constraints |
25
+
26
+ ### Filter Syntax
27
+
28
+ The list tools support pattern matching:
29
+ - `CUST` - Contains "CUST"
30
+ - `CUST*` - Starts with "CUST"
31
+ - `*LOG` - Ends with "LOG"
32
+ - `ORD*FILE` - Starts with "ORD", ends with "FILE"
33
+
34
+ ## Installation
35
+
36
+ ### Prerequisites
37
+
38
+ - Node.js 18 or higher
39
+ - Java Runtime Environment (JRE) 11 or higher (for JDBC)
40
+ - Access to an IBM i system
41
+
42
+ ### Option 1: npm (recommended)
43
+
44
+ ```bash
45
+ npm install -g mcp-server-db2i
46
+ ```
47
+
48
+ ### Option 2: From source
49
+
50
+ ```bash
51
+ git clone https://github.com/Strom-Capital/mcp-server-db2i.git
52
+ cd mcp-server-db2i
53
+ npm install
54
+ npm run build
55
+ ```
56
+
57
+ ### Option 3: Docker
58
+
59
+ ```bash
60
+ docker build -t mcp-server-db2i .
61
+ ```
62
+
63
+ ## Configuration
64
+
65
+ Create a `.env` file or set environment variables:
66
+
67
+ ```env
68
+ # Required
69
+ DB2I_HOSTNAME=your-ibm-i-host.com
70
+ DB2I_USERNAME=your-username
71
+ DB2I_PASSWORD=your-password
72
+
73
+ # Optional
74
+ DB2I_PORT=446 # Default: 446
75
+ DB2I_DATABASE=*LOCAL # Default: *LOCAL
76
+ DB2I_SCHEMA=your-default-schema # Default schema for all tools (can be overridden per-call)
77
+ DB2I_JDBC_OPTIONS=naming=system;date format=iso
78
+ ```
79
+
80
+ ### Environment Variables
81
+
82
+ | Variable | Required | Default | Description |
83
+ |----------|----------|---------|-------------|
84
+ | `DB2I_HOSTNAME` | Yes | - | IBM i hostname or IP address |
85
+ | `DB2I_USERNAME` | Yes | - | IBM i user profile |
86
+ | `DB2I_PASSWORD` | Yes | - | User password |
87
+ | `DB2I_PORT` | No | `446` | JDBC port (446 is standard for IBM i) |
88
+ | `DB2I_DATABASE` | No | `*LOCAL` | Database name |
89
+ | `DB2I_SCHEMA` | No | - | Default schema/library for tools. If set, you don't need to specify schema in each tool call. |
90
+ | `DB2I_JDBC_OPTIONS` | No | - | Additional JDBC options (semicolon-separated) |
91
+
92
+ ### JDBC Options
93
+
94
+ Common JDBC options for IBM i (JT400/JTOpen driver):
95
+
96
+ | Option | Values | Description |
97
+ |--------|--------|-------------|
98
+ | `naming` | `system`, `sql` | `system` uses `/` for library separator, `sql` uses `.` for schema separator |
99
+ | `libraries` | `LIB1,LIB2,...` | Library list for resolving unqualified names |
100
+ | `date format` | `iso`, `usa`, `eur`, `jis`, `mdy`, `dmy`, `ymd` | Date format for date fields |
101
+ | `time format` | `iso`, `usa`, `eur`, `jis`, `hms` | Time format for time fields |
102
+ | `errors` | `full`, `basic` | Level of detail in error messages (`full` helps debugging) |
103
+ | `translate binary` | `true`, `false` | Whether to translate binary/CCSID data |
104
+ | `secure` | `true`, `false` | Enable SSL/TLS encryption |
105
+
106
+ Example: `naming=system;date format=iso;errors=full`
107
+
108
+ ## Usage with Cursor
109
+
110
+ Add to your Cursor MCP settings (`~/.cursor/mcp.json`):
111
+
112
+ ### Using Docker (recommended)
113
+
114
+ ```json
115
+ {
116
+ "mcpServers": {
117
+ "db2i": {
118
+ "command": "docker",
119
+ "args": [
120
+ "run", "-i", "--rm",
121
+ "-e", "DB2I_HOSTNAME=your-host",
122
+ "-e", "DB2I_USERNAME=your-user",
123
+ "-e", "DB2I_PASSWORD=your-password",
124
+ "mcp-server-db2i:latest"
125
+ ]
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ ### Using Docker with env file
132
+
133
+ ```json
134
+ {
135
+ "mcpServers": {
136
+ "db2i": {
137
+ "command": "docker",
138
+ "args": [
139
+ "run", "-i", "--rm",
140
+ "--env-file", "/path/to/your/.env",
141
+ "mcp-server-db2i:latest"
142
+ ]
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ ### Using docker-compose
149
+
150
+ Create a `.env` file in the project root, then:
151
+
152
+ ```json
153
+ {
154
+ "mcpServers": {
155
+ "db2i": {
156
+ "command": "docker-compose",
157
+ "args": ["run", "--rm", "mcp-server-db2i"],
158
+ "cwd": "/path/to/mcp-server-db2i"
159
+ }
160
+ }
161
+ }
162
+ ```
163
+
164
+ The `docker-compose.yml` automatically reads from `.env` in the same directory.
165
+
166
+ ### Using npx (after npm install)
167
+
168
+ ```json
169
+ {
170
+ "mcpServers": {
171
+ "db2i": {
172
+ "command": "npx",
173
+ "args": ["mcp-server-db2i"],
174
+ "env": {
175
+ "DB2I_HOSTNAME": "your-host",
176
+ "DB2I_USERNAME": "your-user",
177
+ "DB2I_PASSWORD": "your-password"
178
+ }
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ ### Local development
185
+
186
+ ```json
187
+ {
188
+ "mcpServers": {
189
+ "db2i": {
190
+ "command": "npx",
191
+ "args": ["tsx", "/path/to/mcp-server-db2i/src/index.ts"],
192
+ "env": {
193
+ "DB2I_HOSTNAME": "your-host",
194
+ "DB2I_USERNAME": "your-user",
195
+ "DB2I_PASSWORD": "your-password"
196
+ }
197
+ }
198
+ }
199
+ }
200
+ ```
201
+
202
+ ## Example Queries
203
+
204
+ Once connected, you can ask the AI assistant:
205
+
206
+ - "List all schemas that contain 'PROD'"
207
+ - "Show me the tables in schema MYLIB"
208
+ - "Describe the columns in MYLIB/CUSTOMERS"
209
+ - "What indexes exist on the ORDERS table?"
210
+ - "Run this query: SELECT * FROM MYLIB.CUSTOMERS WHERE STATUS = 'A'"
211
+
212
+ ## Development
213
+
214
+ ```bash
215
+ # Install dependencies
216
+ npm install
217
+
218
+ # Run in development mode
219
+ npm run dev
220
+
221
+ # Build for production
222
+ npm run build
223
+
224
+ # Run production build
225
+ npm start
226
+ ```
227
+
228
+ ## Security
229
+
230
+ - **Read-only access**: Only SELECT statements are permitted
231
+ - **No credentials in code**: All sensitive data via environment variables
232
+ - **Query validation**: Dangerous SQL keywords are blocked
233
+ - **Result limiting**: Default limit of 1000 rows prevents large result sets
234
+
235
+ ## Compatibility
236
+
237
+ - IBM i V7R3 and later (V7R5 recommended)
238
+ - Works with any IBM i system accessible via JDBC over TCP/IP
239
+
240
+ ## Contributing
241
+
242
+ Contributions are welcome! Please feel free to submit a Pull Request.
243
+
244
+ ## License
245
+
246
+ MIT License - see [LICENSE](LICENSE) for details.
247
+
248
+ ## Acknowledgments
249
+
250
+ - [node-jt400](https://www.npmjs.com/package/node-jt400) - JT400 JDBC driver wrapper for Node.js
251
+ - [Model Context Protocol](https://modelcontextprotocol.io/) - The protocol specification
252
+ - [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) - Official TypeScript SDK
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Configuration module for IBM DB2i MCP Server
3
+ * Handles environment variables and JDBC connection options
4
+ */
5
+ export interface DB2iConfig {
6
+ hostname: string;
7
+ port: number;
8
+ username: string;
9
+ password: string;
10
+ database: string;
11
+ schema: string;
12
+ jdbcOptions: Record<string, string>;
13
+ }
14
+ /**
15
+ * Load configuration from environment variables
16
+ */
17
+ export declare function loadConfig(): DB2iConfig;
18
+ /**
19
+ * Build JDBC connection configuration for node-jt400
20
+ */
21
+ export declare function buildConnectionConfig(config: DB2iConfig): {
22
+ host: string;
23
+ user: string;
24
+ password: string;
25
+ [key: string]: string;
26
+ };
27
+ /**
28
+ * Get the default schema from config
29
+ */
30
+ export declare function getDefaultSchema(config: DB2iConfig): string | undefined;
31
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AA6BD;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAwBvC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB,CA4BA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAEvE"}
package/dist/config.js ADDED
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Configuration module for IBM DB2i MCP Server
3
+ * Handles environment variables and JDBC connection options
4
+ */
5
+ /**
6
+ * Parse JDBC options from a semicolon-separated string
7
+ * Format: "key1=value1;key2=value2"
8
+ */
9
+ function parseJdbcOptions(optionsString) {
10
+ if (!optionsString) {
11
+ return {};
12
+ }
13
+ const options = {};
14
+ const pairs = optionsString.split(';');
15
+ for (const pair of pairs) {
16
+ const trimmed = pair.trim();
17
+ if (!trimmed)
18
+ continue;
19
+ const eqIndex = trimmed.indexOf('=');
20
+ if (eqIndex > 0) {
21
+ const key = trimmed.substring(0, eqIndex).trim();
22
+ const value = trimmed.substring(eqIndex + 1).trim();
23
+ options[key] = value;
24
+ }
25
+ }
26
+ return options;
27
+ }
28
+ /**
29
+ * Load configuration from environment variables
30
+ */
31
+ export function loadConfig() {
32
+ const hostname = process.env.DB2I_HOSTNAME;
33
+ const username = process.env.DB2I_USERNAME;
34
+ const password = process.env.DB2I_PASSWORD;
35
+ if (!hostname) {
36
+ throw new Error('DB2I_HOSTNAME environment variable is required');
37
+ }
38
+ if (!username) {
39
+ throw new Error('DB2I_USERNAME environment variable is required');
40
+ }
41
+ if (!password) {
42
+ throw new Error('DB2I_PASSWORD environment variable is required');
43
+ }
44
+ return {
45
+ hostname,
46
+ port: parseInt(process.env.DB2I_PORT || '446', 10),
47
+ username,
48
+ password,
49
+ database: process.env.DB2I_DATABASE || '*LOCAL',
50
+ schema: process.env.DB2I_SCHEMA || '',
51
+ jdbcOptions: parseJdbcOptions(process.env.DB2I_JDBC_OPTIONS),
52
+ };
53
+ }
54
+ /**
55
+ * Build JDBC connection configuration for node-jt400
56
+ */
57
+ export function buildConnectionConfig(config) {
58
+ const connectionConfig = {
59
+ host: config.hostname,
60
+ user: config.username,
61
+ password: config.password,
62
+ };
63
+ // Add default naming convention (system naming uses / for library separator)
64
+ if (!config.jdbcOptions['naming']) {
65
+ connectionConfig['naming'] = 'system';
66
+ }
67
+ // Add date format if not specified
68
+ if (!config.jdbcOptions['date format']) {
69
+ connectionConfig['date format'] = 'iso';
70
+ }
71
+ // Merge additional JDBC options
72
+ for (const [key, value] of Object.entries(config.jdbcOptions)) {
73
+ connectionConfig[key] = value;
74
+ }
75
+ return connectionConfig;
76
+ }
77
+ /**
78
+ * Get the default schema from config
79
+ */
80
+ export function getDefaultSchema(config) {
81
+ return config.schema || undefined;
82
+ }
83
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * JDBC Connection Manager for IBM DB2i using node-jt400
3
+ */
4
+ import { pool } from 'node-jt400';
5
+ import type { DB2iConfig } from '../config.js';
6
+ export interface QueryResult {
7
+ rows: Record<string, unknown>[];
8
+ metadata?: {
9
+ columnCount: number;
10
+ columns: Array<{
11
+ name: string;
12
+ type: string;
13
+ precision: number;
14
+ scale: number;
15
+ }>;
16
+ };
17
+ }
18
+ /**
19
+ * Initialize the connection pool
20
+ */
21
+ export declare function initializePool(config: DB2iConfig): void;
22
+ /**
23
+ * Get the connection pool instance
24
+ */
25
+ export declare function getPool(): ReturnType<typeof pool>;
26
+ /**
27
+ * Execute a query and return results
28
+ */
29
+ export declare function executeQuery(sql: string, params?: unknown[]): Promise<QueryResult>;
30
+ /**
31
+ * Execute a query with metadata about columns
32
+ */
33
+ export declare function executeQueryWithMetadata(sql: string, params?: unknown[]): Promise<QueryResult>;
34
+ /**
35
+ * Test the database connection
36
+ */
37
+ export declare function testConnection(): Promise<boolean>;
38
+ /**
39
+ * Close the connection pool
40
+ */
41
+ export declare function closePool(): Promise<void>;
42
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,KAAK,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,EAAE,MAAM,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC,CAAC;KACJ,CAAC;CACH;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAGvD;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,UAAU,CAAC,OAAO,IAAI,CAAC,CAKjD;AAkBD;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,OAAO,EAAO,GACrB,OAAO,CAAC,WAAW,CAAC,CActB;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,OAAO,EAAO,GACrB,OAAO,CAAC,WAAW,CAAC,CActB;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAOvD;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/C"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * JDBC Connection Manager for IBM DB2i using node-jt400
3
+ */
4
+ import { pool } from 'node-jt400';
5
+ import { buildConnectionConfig } from '../config.js';
6
+ let connectionPool = null;
7
+ /**
8
+ * Initialize the connection pool
9
+ */
10
+ export function initializePool(config) {
11
+ const connectionConfig = buildConnectionConfig(config);
12
+ connectionPool = pool(connectionConfig);
13
+ }
14
+ /**
15
+ * Get the connection pool instance
16
+ */
17
+ export function getPool() {
18
+ if (!connectionPool) {
19
+ throw new Error('Connection pool not initialized. Call initializePool first.');
20
+ }
21
+ return connectionPool;
22
+ }
23
+ /**
24
+ * Convert unknown params to Param type, filtering out undefined
25
+ */
26
+ function toParams(params) {
27
+ return params
28
+ .filter((p) => p !== undefined)
29
+ .map((p) => {
30
+ if (p === null)
31
+ return null;
32
+ if (typeof p === 'string')
33
+ return p;
34
+ if (typeof p === 'number')
35
+ return p;
36
+ if (p instanceof Date)
37
+ return p;
38
+ // Convert other types to string
39
+ return String(p);
40
+ });
41
+ }
42
+ /**
43
+ * Execute a query and return results
44
+ */
45
+ export async function executeQuery(sql, params = []) {
46
+ const db = getPool();
47
+ try {
48
+ const typedParams = toParams(params);
49
+ const results = await db.query(sql, typedParams);
50
+ return {
51
+ rows: results,
52
+ };
53
+ }
54
+ catch (error) {
55
+ const message = error instanceof Error ? error.message : 'Unknown database error';
56
+ throw new Error(`Database query failed: ${message}`);
57
+ }
58
+ }
59
+ /**
60
+ * Execute a query with metadata about columns
61
+ */
62
+ export async function executeQueryWithMetadata(sql, params = []) {
63
+ const db = getPool();
64
+ try {
65
+ const typedParams = toParams(params);
66
+ const results = await db.query(sql, typedParams);
67
+ return {
68
+ rows: results,
69
+ };
70
+ }
71
+ catch (error) {
72
+ const message = error instanceof Error ? error.message : 'Unknown database error';
73
+ throw new Error(`Database query failed: ${message}`);
74
+ }
75
+ }
76
+ /**
77
+ * Test the database connection
78
+ */
79
+ export async function testConnection() {
80
+ try {
81
+ await executeQuery('SELECT 1 FROM SYSIBM.SYSDUMMY1');
82
+ return true;
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ /**
89
+ * Close the connection pool
90
+ */
91
+ export async function closePool() {
92
+ if (connectionPool) {
93
+ // node-jt400 pool doesn't have explicit close, but we can clear the reference
94
+ connectionPool = null;
95
+ }
96
+ }
97
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Query helpers for IBM DB2i metadata and data access
3
+ */
4
+ /**
5
+ * Convert a filter pattern to SQL LIKE pattern
6
+ * Supports:
7
+ * - "term" -> "%term%" (contains)
8
+ * - "term*" -> "term%" (starts with)
9
+ * - "*term" -> "%term" (ends with)
10
+ * - "term*suffix" -> "term%suffix" (pattern)
11
+ */
12
+ export declare function filterToLikePattern(filter: string | undefined): string;
13
+ /**
14
+ * Validate that a query is read-only (SELECT only)
15
+ */
16
+ export declare function isReadOnlyQuery(sql: string): boolean;
17
+ /**
18
+ * List all schemas/libraries
19
+ */
20
+ export declare function listSchemas(filter?: string): Promise<Array<{
21
+ schema_name: string;
22
+ schema_text: string | null;
23
+ }>>;
24
+ /**
25
+ * List tables in a schema
26
+ */
27
+ export declare function listTables(schema: string, filter?: string): Promise<Array<{
28
+ table_name: string;
29
+ table_type: string;
30
+ table_text: string | null;
31
+ }>>;
32
+ /**
33
+ * Describe a table's columns
34
+ */
35
+ export declare function describeTable(schema: string, table: string): Promise<Array<{
36
+ column_name: string;
37
+ ordinal_position: number;
38
+ data_type: string;
39
+ length: number | null;
40
+ numeric_scale: number | null;
41
+ is_nullable: string;
42
+ column_default: string | null;
43
+ column_text: string | null;
44
+ system_column_name: string;
45
+ ccsid: number | null;
46
+ }>>;
47
+ /**
48
+ * List views in a schema
49
+ */
50
+ export declare function listViews(schema: string, filter?: string): Promise<Array<{
51
+ view_name: string;
52
+ view_text: string | null;
53
+ }>>;
54
+ /**
55
+ * List indexes for a table
56
+ */
57
+ export declare function listIndexes(schema: string, table: string): Promise<Array<{
58
+ index_name: string;
59
+ index_schema: string;
60
+ is_unique: string;
61
+ column_names: string;
62
+ }>>;
63
+ /**
64
+ * Get table constraints (primary keys, foreign keys, unique constraints)
65
+ */
66
+ export declare function getTableConstraints(schema: string, table: string): Promise<Array<{
67
+ constraint_name: string;
68
+ constraint_type: string;
69
+ column_name: string;
70
+ ordinal_position: number;
71
+ referenced_table_schema: string | null;
72
+ referenced_table_name: string | null;
73
+ referenced_column_name: string | null;
74
+ }>>;
75
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAiBtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAgCpD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC,CAkBtH;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC,CAqBvF;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,KAAK,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC,CAAC,CAiCF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC,CAoBjE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,KAAK,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC,CAqBF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,KAAK,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC,CAAC,CAAC,CAqCF"}