agent-database-cli 0.2.7
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/AI_INSTALL.md +72 -0
- package/LICENSE +21 -0
- package/README.md +340 -0
- package/README_EN.md +341 -0
- package/SKILL.md +252 -0
- package/config/docker-test.json +40 -0
- package/dist/adapters/base-sql.d.ts +12 -0
- package/dist/adapters/base-sql.js +22 -0
- package/dist/adapters/base-sql.js.map +1 -0
- package/dist/adapters/factory.d.ts +2 -0
- package/dist/adapters/factory.js +26 -0
- package/dist/adapters/factory.js.map +1 -0
- package/dist/adapters/mongodb.d.ts +14 -0
- package/dist/adapters/mongodb.js +137 -0
- package/dist/adapters/mongodb.js.map +1 -0
- package/dist/adapters/mysql.d.ts +12 -0
- package/dist/adapters/mysql.js +38 -0
- package/dist/adapters/mysql.js.map +1 -0
- package/dist/adapters/oracle-sqlcl.d.ts +19 -0
- package/dist/adapters/oracle-sqlcl.js +334 -0
- package/dist/adapters/oracle-sqlcl.js.map +1 -0
- package/dist/adapters/oracle.d.ts +13 -0
- package/dist/adapters/oracle.js +47 -0
- package/dist/adapters/oracle.js.map +1 -0
- package/dist/adapters/postgres.d.ts +12 -0
- package/dist/adapters/postgres.js +40 -0
- package/dist/adapters/postgres.js.map +1 -0
- package/dist/adapters/redis.d.ts +15 -0
- package/dist/adapters/redis.js +91 -0
- package/dist/adapters/redis.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +118 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +147 -0
- package/dist/config.js.map +1 -0
- package/dist/connection-manager.d.ts +24 -0
- package/dist/connection-manager.js +91 -0
- package/dist/connection-manager.js.map +1 -0
- package/dist/daemon/client.d.ts +3 -0
- package/dist/daemon/client.js +33 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/config-manager.d.ts +15 -0
- package/dist/daemon/config-manager.js +44 -0
- package/dist/daemon/config-manager.js.map +1 -0
- package/dist/daemon/control.d.ts +9 -0
- package/dist/daemon/control.js +53 -0
- package/dist/daemon/control.js.map +1 -0
- package/dist/daemon/paths.d.ts +5 -0
- package/dist/daemon/paths.js +18 -0
- package/dist/daemon/paths.js.map +1 -0
- package/dist/daemon/server.d.ts +1 -0
- package/dist/daemon/server.js +119 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/output.d.ts +2 -0
- package/dist/output.js +39 -0
- package/dist/output.js.map +1 -0
- package/dist/runtime.d.ts +5 -0
- package/dist/runtime.js +25 -0
- package/dist/runtime.js.map +1 -0
- package/dist/security.d.ts +8 -0
- package/dist/security.js +239 -0
- package/dist/security.js.map +1 -0
- package/dist/ssh-tunnel.d.ts +8 -0
- package/dist/ssh-tunnel.js +231 -0
- package/dist/ssh-tunnel.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/masking.d.ts +2 -0
- package/dist/utils/masking.js +14 -0
- package/dist/utils/masking.js.map +1 -0
- package/package.json +50 -0
package/README_EN.md
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# agent-database-cli
|
|
4
|
+
|
|
5
|
+
A CLI-based multi-database tool that packages common database connection, query, metadata inspection, and connection reuse capabilities as local commands callable by agents.
|
|
6
|
+
|
|
7
|
+
MySQL · PostgreSQL · Redis · Oracle · MongoDB · Read-only mode · Command blocklist · SQLcl Oracle · Local daemon
|
|
8
|
+
|
|
9
|
+
<p>
|
|
10
|
+
<img src="https://img.shields.io/badge/CLI-agent--database--cli-2ea44f" alt="CLI agent-database-cli">
|
|
11
|
+
<img src="https://img.shields.io/badge/License-MIT-green" alt="License MIT">
|
|
12
|
+
<img src="https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&logoColor=white" alt="Node.js >=20">
|
|
13
|
+
<img src="https://img.shields.io/badge/npm-%3E%3D10-CB3837?logo=npm&logoColor=white" alt="npm >=10">
|
|
14
|
+
<img src="https://img.shields.io/badge/Windows-MacOS-0078D6?labelColor=0078D6&color=C0C0C0" alt="Windows/MacOS">
|
|
15
|
+
<img src="https://img.shields.io/badge/release-v0.2.6-blue" alt="release v0.2.6">
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
[AI One-Click Installation](#ai-one-click-installation) · [Installation](#installation) · [Configuration](#configuration) · [Permission Configuration](#permission-configuration) · [Oracle SQLcl](#oracle-sqlcl) · [License](#license) · [Friendly Links](#friendly-links)
|
|
19
|
+
|
|
20
|
+
[中文](README.md) | English
|
|
21
|
+
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
## Introduction
|
|
25
|
+
|
|
26
|
+
`agent-database-cli` references the database adapter, config loading, safety checking, and connection management layering of [Anarkh-Lee/universal-db-mcp](https://github.com/Anarkh-Lee/universal-db-mcp), then rewrites it into a standalone CLI form without MCP, HTTP, or SSE services.
|
|
27
|
+
|
|
28
|
+
What it can do:
|
|
29
|
+
|
|
30
|
+
- List currently supported database types and locally configured connections
|
|
31
|
+
- Execute SQL, Redis commands, or MongoDB JSON commands against a specified database
|
|
32
|
+
- Query database metadata such as tables, columns, collections, and Redis keys
|
|
33
|
+
- Enable read-only mode and command blocklists per database configuration
|
|
34
|
+
- Auto-start the local daemon on demand; the daemon exits after `300` idle seconds by default
|
|
35
|
+
- Keep connections alive through the local daemon; each database connection is released after `180` idle seconds by default
|
|
36
|
+
- Switch Oracle between `oracledb` and SQLcl drivers
|
|
37
|
+
- Never store or print unmasked passwords, tokens, or secrets
|
|
38
|
+
- Use named pipes on Windows and Unix sockets on macOS/Linux for the daemon
|
|
39
|
+
|
|
40
|
+
Driver configuration table:
|
|
41
|
+
|
|
42
|
+
| Database | `type` | Default driver | Driver switch configuration | Common configuration |
|
|
43
|
+
| --- | --- | --- | --- | --- |
|
|
44
|
+
| MySQL | `mysql` | npm package `mysql2` | Not switchable yet | `readonly`, `blacklist`, `keepAliveSeconds` |
|
|
45
|
+
| PostgreSQL | `postgres` | npm package `pg` | Not switchable yet | `readonly`, `blacklist`, `keepAliveSeconds` |
|
|
46
|
+
| Redis standalone | `redis` | npm package `redis` | Configure `url` only | `readonly`, `blacklist`, `keepAliveSeconds` |
|
|
47
|
+
| Redis cluster | `redis` | npm package `redis` | Configure both `url` and `redisCluster.nodes` | `readonly`, `blacklist`, `keepAliveSeconds` |
|
|
48
|
+
| Oracle | `oracle` | npm package `oracledb` | `oracleDriver: "oracledb" \| "sqlcl"`; SQLcl mode can configure `sqlclPath` and `javaHome`. SQLcl is recommended for older Oracle versions | `readonly`, `blacklist`, `keepAliveSeconds` |
|
|
49
|
+
| MongoDB | `mongodb` | npm package `mongodb` | Not switchable yet; `database` can be configured as the default database | `readonly`, `blacklist`, `keepAliveSeconds` |
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
### Requirements
|
|
54
|
+
|
|
55
|
+
- Node.js `>= 20`
|
|
56
|
+
- npm `>= 10`
|
|
57
|
+
- Local network access to the target database
|
|
58
|
+
- Docker and Docker Compose if you run integration tests
|
|
59
|
+
- SQLcl and Java installed locally if Oracle uses SQLcl
|
|
60
|
+
|
|
61
|
+
### AI One-Click Installation
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
Please read https://github.com/sleepinginsummer/agent-database-cli/blob/main/AI_INSTALL.md, install the CLI as instructed, and add `SKILL.md`.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Manual Global Installation
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install -g agent-database-cli
|
|
71
|
+
agent-database-cli --help
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If npm package installation is restricted, use the equivalent source installation flow:
|
|
75
|
+
|
|
76
|
+
```powershell
|
|
77
|
+
git clone https://github.com/sleepinginsummer/agent-database-cli.git
|
|
78
|
+
cd agent-database-cli
|
|
79
|
+
npm install
|
|
80
|
+
npm run build
|
|
81
|
+
npm link
|
|
82
|
+
agent-database-cli --help
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Add `SKILL.md` to the agent that needs to use this tool.
|
|
86
|
+
|
|
87
|
+
## Configuration
|
|
88
|
+
|
|
89
|
+
Default configuration file:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
~/.agent-database-cli/config.json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
You can override the configuration path with an environment variable:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
AGENT_DATABASE_CLI_CONFIG=/path/to/config.json agent-database-cli list
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The configuration file is an object. Each key under `databases` is a database connection name:
|
|
102
|
+
|
|
103
|
+
- `type`: Database type, supports `mysql`, `postgres`, `redis`, `oracle`, and `mongodb`
|
|
104
|
+
- `url`: Database connection URL. In Redis standalone mode it is the direct target. In Redis cluster mode it is used as the entry node URL
|
|
105
|
+
- `redisCluster`: Optional Redis cluster configuration. When configured, cluster mode is used
|
|
106
|
+
- `sshTunnel`: Optional SSH tunnel configuration. In standalone mode, the database URL host and port are forwarded through SSH. In Redis cluster mode, a local forwarding port is created for each configured cluster node
|
|
107
|
+
- `database`: Optional default MongoDB database name
|
|
108
|
+
- `readonly`: Whether read-only mode is enabled, default `true`; only explicitly set `false` when write access is really required
|
|
109
|
+
- `blacklist`: Command blocklist array, case-insensitive
|
|
110
|
+
- `keepAliveSeconds`: Idle release timeout in seconds for a single database connection, default `180`
|
|
111
|
+
- `oracleDriver`: Oracle driver, supports `oracledb` or `sqlcl`
|
|
112
|
+
- `sqlclPath`: SQLcl executable path, used only when `oracleDriver` is `sqlcl`
|
|
113
|
+
- `javaHome`: Optional `JAVA_HOME` used by SQLcl
|
|
114
|
+
|
|
115
|
+
`redisCluster` currently supports:
|
|
116
|
+
|
|
117
|
+
- `nodes`: Array of Redis cluster node URLs. At least one node is required. `redis://` and `rediss://` are supported
|
|
118
|
+
|
|
119
|
+
Redis cluster notes:
|
|
120
|
+
|
|
121
|
+
- In the current implementation, Redis cluster mode requires both `url` and `redisCluster.nodes`
|
|
122
|
+
- `url` is used as the cluster entry node. It is recommended to use any stable reachable cluster node URL
|
|
123
|
+
- `redisCluster.nodes` is used as the cluster node list. With SSH tunneling, it is also used to create per-node local forwarding and address mapping
|
|
124
|
+
- When `redisCluster.nodes` is configured, the client switches to Redis Cluster mode
|
|
125
|
+
- When `sshTunnel` is also configured, the program creates a local forwarded port for each cluster node and uses address mapping for cluster redirects
|
|
126
|
+
- With SSH tunneling, `redisCluster.nodes` should cover the cluster node addresses that the client may be redirected to
|
|
127
|
+
|
|
128
|
+
`sshTunnel` supports password, private key, password plus private key, and passphrase-protected private key authentication:
|
|
129
|
+
|
|
130
|
+
- `host`: SSH jump host address
|
|
131
|
+
- `port`: SSH port, default `22`
|
|
132
|
+
- `username`: SSH username
|
|
133
|
+
- `password`: Optional SSH password
|
|
134
|
+
- `privateKeyPath`: Optional private key file path, supports `~`
|
|
135
|
+
- `privateKey`: Optional private key content, mutually exclusive with `privateKeyPath`
|
|
136
|
+
- `passphrase`: Optional private key passphrase, only valid when a private key is configured
|
|
137
|
+
- `readyTimeout`: Optional SSH connection timeout in milliseconds
|
|
138
|
+
|
|
139
|
+
The blocklist and read-only mode work together with a fixed priority: check the blocklist first, reject immediately on match, and only check read-only mode when no blocklist rule matches.
|
|
140
|
+
|
|
141
|
+
Read-only mode notes:
|
|
142
|
+
|
|
143
|
+
- Read-only mode is enabled by default; write operations are still rejected when `readonly` is omitted
|
|
144
|
+
- It is recommended to keep all database connections read-only by default. When data changes are needed, let AI generate the SQL or command first, then execute it after your confirmation
|
|
145
|
+
- Only set `readonly: false` on a specific connection when write access is truly required
|
|
146
|
+
|
|
147
|
+
Reference configuration:
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"databases": {
|
|
152
|
+
"local-mysql": {
|
|
153
|
+
"type": "mysql",
|
|
154
|
+
"url": "mysql://user:password@localhost:3306/app",
|
|
155
|
+
"readonly": true,
|
|
156
|
+
"blacklist": ["drop", "truncate", "delete"],
|
|
157
|
+
"keepAliveSeconds": 180
|
|
158
|
+
},
|
|
159
|
+
"remote-mysql": {
|
|
160
|
+
"type": "mysql",
|
|
161
|
+
"url": "mysql://user:password@db.internal:3306/app",
|
|
162
|
+
"sshTunnel": {
|
|
163
|
+
"host": "jump.example.com",
|
|
164
|
+
"port": 22,
|
|
165
|
+
"username": "deploy",
|
|
166
|
+
"privateKeyPath": "~/.ssh/id_rsa",
|
|
167
|
+
"passphrase": "key-passphrase"
|
|
168
|
+
},
|
|
169
|
+
"readonly": true,
|
|
170
|
+
"keepAliveSeconds": 180
|
|
171
|
+
},
|
|
172
|
+
"redis-standalone": {
|
|
173
|
+
"type": "redis",
|
|
174
|
+
"url": "redis://localhost:6379",
|
|
175
|
+
"readonly": false,
|
|
176
|
+
"blacklist": ["flushall", "flushdb"],
|
|
177
|
+
"keepAliveSeconds": 180
|
|
178
|
+
},
|
|
179
|
+
"redis-cluster": {
|
|
180
|
+
"type": "redis",
|
|
181
|
+
"url": "redis://10.0.0.11:7001",
|
|
182
|
+
"redisCluster": {
|
|
183
|
+
"nodes": [
|
|
184
|
+
"redis://10.0.0.11:7001",
|
|
185
|
+
"redis://10.0.0.12:7001",
|
|
186
|
+
"redis://10.0.0.13:7001"
|
|
187
|
+
]
|
|
188
|
+
},
|
|
189
|
+
"readonly": true,
|
|
190
|
+
"blacklist": ["flushall", "flushdb"],
|
|
191
|
+
"keepAliveSeconds": 180
|
|
192
|
+
},
|
|
193
|
+
"redis-cluster-via-ssh": {
|
|
194
|
+
"type": "redis",
|
|
195
|
+
"url": "redis://10.0.0.11:7001",
|
|
196
|
+
"redisCluster": {
|
|
197
|
+
"nodes": [
|
|
198
|
+
"redis://10.0.0.11:7001",
|
|
199
|
+
"redis://10.0.0.12:7001",
|
|
200
|
+
"redis://10.0.0.13:7001"
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
"sshTunnel": {
|
|
204
|
+
"host": "jump.example.com",
|
|
205
|
+
"port": 22,
|
|
206
|
+
"username": "deploy",
|
|
207
|
+
"privateKeyPath": "~/.ssh/id_rsa"
|
|
208
|
+
},
|
|
209
|
+
"readonly": true,
|
|
210
|
+
"blacklist": ["flushall", "flushdb"],
|
|
211
|
+
"keepAliveSeconds": 180
|
|
212
|
+
},
|
|
213
|
+
"oracle-test": {
|
|
214
|
+
"type": "oracle",
|
|
215
|
+
"url": "oracle://USER:password@127.0.0.1:1521/qftest201",
|
|
216
|
+
"oracleDriver": "sqlcl",
|
|
217
|
+
"sqlclPath": "/opt/homebrew/Caskroom/sqlcl/26.1.0.086.1709/sqlcl/bin/sql",
|
|
218
|
+
"javaHome": "/Applications/IntelliJ IDEA Ultimate.app/Contents/jbr/Contents/Home",
|
|
219
|
+
"readonly": true,
|
|
220
|
+
"blacklist": ["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create"],
|
|
221
|
+
"keepAliveSeconds": 180
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Permission Configuration
|
|
228
|
+
|
|
229
|
+
It is recommended to use both `readonly` and `blacklist` together for permission control. Do not rely on only one of them.
|
|
230
|
+
|
|
231
|
+
### Read-only Mode
|
|
232
|
+
|
|
233
|
+
- The default value is `true`
|
|
234
|
+
- When `readonly` is omitted, the connection is still treated as read-only
|
|
235
|
+
- It is recommended to keep all day-to-day query connections read-only by default
|
|
236
|
+
- When data changes are needed, let AI generate the SQL or command first, then execute it after your confirmation
|
|
237
|
+
- Only dedicated writable connections should explicitly set `readonly: false`
|
|
238
|
+
|
|
239
|
+
### Command Blocklist
|
|
240
|
+
|
|
241
|
+
- The blocklist has higher priority than read-only mode
|
|
242
|
+
- A command is rejected immediately once it matches the blocklist
|
|
243
|
+
- It is suitable for blocking high-risk commands such as dropping data, schema changes, mass writes, and cache-clearing operations
|
|
244
|
+
- It is recommended for production databases, shared test databases, and online Redis instances
|
|
245
|
+
|
|
246
|
+
### Execution Order
|
|
247
|
+
|
|
248
|
+
1. Check `blacklist` first
|
|
249
|
+
2. Reject immediately on match
|
|
250
|
+
3. Check `readonly` only when not matched
|
|
251
|
+
4. When `readonly` is enabled, only read commands are allowed
|
|
252
|
+
|
|
253
|
+
### Common High-Risk Commands
|
|
254
|
+
|
|
255
|
+
Common high-risk SQL for MySQL / PostgreSQL / Oracle:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create", "replace", "grant", "revoke"]
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Common high-risk Redis commands:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
["flushall", "flushdb", "del", "unlink", "set", "mset", "expire", "rename", "hset", "lpush", "rpush", "sadd", "zadd"]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Common high-risk MongoDB commands:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
["insertOne", "insertMany", "updateOne", "updateMany", "replaceOne", "deleteOne", "deleteMany", "findAndModify", "findOneAndUpdate", "findOneAndDelete", "drop", "dropDatabase", "createIndex", "dropIndex"]
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Recommended Configuration Examples
|
|
274
|
+
|
|
275
|
+
Recommended for production databases:
|
|
276
|
+
|
|
277
|
+
```json
|
|
278
|
+
{
|
|
279
|
+
"type": "mysql",
|
|
280
|
+
"url": "mysql://user:password@prod-db:3306/app",
|
|
281
|
+
"readonly": true,
|
|
282
|
+
"blacklist": ["drop", "truncate", "delete", "update", "insert", "alter", "create"],
|
|
283
|
+
"keepAliveSeconds": 180
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Recommended for a dedicated writable connection:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{
|
|
291
|
+
"type": "postgres",
|
|
292
|
+
"url": "postgres://user:password@write-db:5432/app",
|
|
293
|
+
"readonly": false,
|
|
294
|
+
"blacklist": ["drop", "truncate", "alter"],
|
|
295
|
+
"keepAliveSeconds": 180
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Oracle SQLcl
|
|
300
|
+
|
|
301
|
+
Official link: https://www.oracle.com/database/sqldeveloper/technologies/sqlcl/
|
|
302
|
+
|
|
303
|
+
Oracle uses the npm package `oracledb` by default. If the target Oracle version is older, Thin mode compatibility errors such as `NJS-138` may appear. In that case, switch a single Oracle connection to SQLcl:
|
|
304
|
+
|
|
305
|
+
```json
|
|
306
|
+
{
|
|
307
|
+
"type": "oracle",
|
|
308
|
+
"url": "oracle://USER:password@127.0.0.1:1521/qftest201",
|
|
309
|
+
"oracleDriver": "sqlcl",
|
|
310
|
+
"sqlclPath": "/opt/homebrew/Caskroom/sqlcl/26.1.0.086.1709/sqlcl/bin/sql",
|
|
311
|
+
"javaHome": "/Applications/IntelliJ IDEA Ultimate.app/Contents/jbr/Contents/Home",
|
|
312
|
+
"readonly": true,
|
|
313
|
+
"blacklist": ["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create"]
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
SQLcl mode passes the connection script through stdin to avoid exposing the password in process arguments. Security checks still happen before execution, and both blocklist and read-only mode remain effective.
|
|
318
|
+
|
|
319
|
+
## Update
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
npm install -g agent-database-cli@latest
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Uninstall and Cleanup
|
|
326
|
+
|
|
327
|
+
Uninstall and clean local configuration:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npm uninstall -g agent-database-cli
|
|
331
|
+
npm cache clean --force
|
|
332
|
+
rm -rf ~/.agent-database-cli
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
[MIT](LICENSE)
|
|
338
|
+
|
|
339
|
+
## Friendly Links
|
|
340
|
+
|
|
341
|
+
- [LINUX DO - A New Ideal Community](https://linux.do/)
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-database-cli
|
|
3
|
+
description: 使用本地 agent-database-cli 安全操作已配置的数据库。适用于列出数据库连接、测试连接、执行 SQL/Redis/MongoDB 命令、查询表/列/集合/keys 元信息、管理本地连接 daemon,以及验证只读模式和命令黑名单的场景。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# agent-database-cli 使用说明
|
|
7
|
+
|
|
8
|
+
`agent-database-cli` 是一个基于本地配置的多数据库命令行工具,用于让 AI 或用户安全地操作数据库。
|
|
9
|
+
|
|
10
|
+
它能做的事:
|
|
11
|
+
|
|
12
|
+
- 列出支持的数据库类型和本地已配置数据库连接
|
|
13
|
+
- 测试指定数据库连接
|
|
14
|
+
- 执行 SQL、Redis 命令或 MongoDB JSON 命令
|
|
15
|
+
- 查询表、列、集合、Redis keys 等元信息
|
|
16
|
+
- 按单个数据库配置执行命令黑名单和只读模式
|
|
17
|
+
- 普通命令会按需自动启动本地 daemon,daemon 默认空闲 `300` 秒后自动退出
|
|
18
|
+
- 通过本地 daemon 短时间保持连接,单个数据库连接默认空闲 `180` 秒释放
|
|
19
|
+
- daemon 在 Windows 使用 named pipe,在 macOS/Linux 使用 Unix socket
|
|
20
|
+
- Oracle 支持 `oracledb` 和 SQLcl 两种连接方式
|
|
21
|
+
|
|
22
|
+
它不做的事:
|
|
23
|
+
|
|
24
|
+
- 不扫描网络或发现数据库,只使用配置文件中的连接
|
|
25
|
+
- 不绕过配置中的黑名单和只读模式
|
|
26
|
+
- 不输出未脱敏的密码、token、secret
|
|
27
|
+
- 不默认执行写入、删除、DDL 或其它危险命令
|
|
28
|
+
|
|
29
|
+
## 安全确认
|
|
30
|
+
|
|
31
|
+
执行任何可能写入、删除、修改结构或影响数据完整性的命令前,必须先确认目标数据库配置是否启用了 `readonly` 和 `blacklist`。
|
|
32
|
+
|
|
33
|
+
危险操作包括:
|
|
34
|
+
|
|
35
|
+
- DDL:`drop`、`truncate`、`alter`、`create`
|
|
36
|
+
- DML 写入:`insert`、`update`、`delete`、`merge`
|
|
37
|
+
- Redis 清空或写入:`flushall`、`flushdb`、`set`、`del`
|
|
38
|
+
- MongoDB 写入或删除:`insertOne`、`updateOne`、`deleteMany`、`drop`、`dropDatabase`
|
|
39
|
+
- 任何不可逆、影响生产数据、影响结构或权限的命令
|
|
40
|
+
|
|
41
|
+
如果用户明确要求执行危险命令,先说明目标数据库名、命令、可能影响,并等待用户明确同意。即使用户同意,也不能绕过本项目配置中的黑名单和只读模式。
|
|
42
|
+
|
|
43
|
+
黑名单优先级高于只读模式。命令执行前先检查 `blacklist`,命中后直接拒绝;未命中时再检查 `readonly`。
|
|
44
|
+
|
|
45
|
+
读取配置文件json前需要用户确认,防止密钥泄露。
|
|
46
|
+
|
|
47
|
+
## 环境校验
|
|
48
|
+
|
|
49
|
+
调用前优先检查 CLI 是否可用:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
agent-database-cli --help
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
如果上面的命令失败,检查基础环境:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
node --version
|
|
60
|
+
npm --version
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
如果依赖或构建产物缺失,在项目目录中执行:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install
|
|
67
|
+
npm run build
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
默认配置文件:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
~/.agent-database-cli/config.json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
指定其它配置文件:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
AGENT_DATABASE_CLI_CONFIG=/path/to/config.json agent-database-cli list
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 配置格式
|
|
83
|
+
|
|
84
|
+
配置文件是 JSON 对象,根字段为 `databases`:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"databases": {
|
|
89
|
+
"local-mysql": {
|
|
90
|
+
"type": "mysql",
|
|
91
|
+
"url": "mysql://user:password@localhost:3306/app",
|
|
92
|
+
"readonly": true,
|
|
93
|
+
"blacklist": ["drop", "truncate", "delete"],
|
|
94
|
+
"keepAliveSeconds": 180
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
字段:
|
|
101
|
+
|
|
102
|
+
- `type`: `mysql`、`postgres`、`redis`、`oracle`、`mongodb`
|
|
103
|
+
- `url`: 数据库连接 URL
|
|
104
|
+
- `database`: MongoDB 默认数据库名,可选
|
|
105
|
+
- `readonly`: 是否启用只读模式
|
|
106
|
+
- `blacklist`: 命令黑名单数组,大小写不敏感
|
|
107
|
+
- `keepAliveSeconds`: daemon 连接空闲释放秒数,默认 `180`
|
|
108
|
+
- `oracleDriver`: Oracle 驱动,可选 `oracledb` 或 `sqlcl`
|
|
109
|
+
- `sqlclPath`: SQLcl 可执行文件路径
|
|
110
|
+
- `javaHome`: SQLcl 使用的 `JAVA_HOME`
|
|
111
|
+
|
|
112
|
+
## 全局参数
|
|
113
|
+
|
|
114
|
+
- `--format <format>`: 输出格式,支持 `json` 或 `table`,默认 `json`
|
|
115
|
+
- `--help`, `-h`: 输出帮助
|
|
116
|
+
- `--version`, `-V`: 输出版本
|
|
117
|
+
|
|
118
|
+
配置路径通过环境变量传递:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
AGENT_DATABASE_CLI_CONFIG=/path/to/config.json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## list
|
|
125
|
+
|
|
126
|
+
列出支持的数据库类型、已配置连接和配置文件路径。
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
agent-database-cli list
|
|
130
|
+
agent-database-cli --format table list
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
返回值:
|
|
135
|
+
|
|
136
|
+
- 成功时 stdout 输出 JSON 或表格
|
|
137
|
+
- 输出包含 `supported`、`configured`、`configPath`
|
|
138
|
+
- 配置文件不存在时仍会输出支持列表,`configured` 为空
|
|
139
|
+
- 退出码为 `0`
|
|
140
|
+
|
|
141
|
+
## test
|
|
142
|
+
|
|
143
|
+
测试指定数据库连接。
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
agent-database-cli test --db "<databaseName>"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
返回值:
|
|
150
|
+
|
|
151
|
+
- 成功时 stdout 输出 `{ "ok": true }`
|
|
152
|
+
- 连接失败、配置缺失或认证失败时 stderr 输出错误,退出码为 `1`
|
|
153
|
+
|
|
154
|
+
## exec
|
|
155
|
+
|
|
156
|
+
统一执行 SQL、Redis 命令或 MongoDB JSON 命令。
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
agent-database-cli exec --db "<databaseName>" --command "<command>"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
示例:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
agent-database-cli exec --db local-mysql --command "select 1"
|
|
166
|
+
agent-database-cli exec --db cache --command "GET user:1"
|
|
167
|
+
agent-database-cli exec --db local-mongodb --command '{"find":{"collection":"users","filter":{},"limit":1}}'
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
返回值:
|
|
171
|
+
|
|
172
|
+
- 成功时 stdout 输出 `rows`、`fields`、`rowCount`
|
|
173
|
+
- 命中黑名单、违反只读模式、命令执行失败时 stderr 输出错误,退出码为 `1`
|
|
174
|
+
- SQLcl Oracle 模式返回 SQLcl 文本输出,字段名为 `output`
|
|
175
|
+
|
|
176
|
+
## meta
|
|
177
|
+
|
|
178
|
+
查询数据库元信息。
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
agent-database-cli meta --db "<databaseName>" --type tables
|
|
182
|
+
agent-database-cli meta --db "<databaseName>" --type columns --table users
|
|
183
|
+
agent-database-cli meta --db "<databaseName>" --type collections
|
|
184
|
+
agent-database-cli meta --db "<databaseName>" --type keys --pattern "user:*"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
参数:
|
|
188
|
+
|
|
189
|
+
- `--db <name>`: 数据库配置名
|
|
190
|
+
- `--type <type>`: `tables`、`columns`、`collections`、`keys`
|
|
191
|
+
- `--table <table>`: `columns` 查询所需表名
|
|
192
|
+
- `--pattern <pattern>`: Redis keys 匹配模式
|
|
193
|
+
|
|
194
|
+
返回值:
|
|
195
|
+
|
|
196
|
+
- 成功时 stdout 输出查询结果
|
|
197
|
+
- 当前数据库不支持的元信息类型会失败并返回错误
|
|
198
|
+
|
|
199
|
+
## daemon
|
|
200
|
+
|
|
201
|
+
管理本地连接守护进程。普通 `test`、`exec`、`meta`、`reset` 命令会在 daemon 未运行时自动启动 daemon,已运行时直接复用,不会重复启动。daemon 使用 Unix socket,不暴露网络端口,默认空闲 `300` 秒后自动退出。
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
agent-database-cli daemon start
|
|
205
|
+
agent-database-cli daemon status
|
|
206
|
+
agent-database-cli daemon stop
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
返回值:
|
|
210
|
+
|
|
211
|
+
- `start` 成功时输出 socket 路径
|
|
212
|
+
- `status` 成功时输出当前连接列表
|
|
213
|
+
- `stop` 成功时输出停止结果
|
|
214
|
+
|
|
215
|
+
## reset
|
|
216
|
+
|
|
217
|
+
重置指定数据库连接。
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
agent-database-cli reset --db "<databaseName>"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
如果 daemon 正在运行,会断开并清理该数据库连接;下一次命令会重新连接。
|
|
224
|
+
|
|
225
|
+
## Oracle SQLcl
|
|
226
|
+
|
|
227
|
+
当 Oracle `oracledb` Thin mode 不支持目标库版本时,可以改用 SQLcl。
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"type": "oracle",
|
|
232
|
+
"url": "oracle://USER:password@192.0.2.20:1521/qftest201",
|
|
233
|
+
"oracleDriver": "sqlcl",
|
|
234
|
+
"sqlclPath": "/opt/homebrew/Caskroom/sqlcl/26.1.0.086.1709/sqlcl/bin/sql",
|
|
235
|
+
"javaHome": "/Applications/IntelliJ IDEA Ultimate.app/Contents/jbr/Contents/Home",
|
|
236
|
+
"readonly": true,
|
|
237
|
+
"blacklist": ["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create"]
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
SQLcl 模式通过 stdin 传入连接脚本,避免密码出现在命令行参数列表中。执行前仍会先走本地黑名单和只读检查。
|
|
242
|
+
|
|
243
|
+
## 错误规则
|
|
244
|
+
|
|
245
|
+
- 配置文件 JSON 无效时失败
|
|
246
|
+
- `databases` 缺失或数据库配置名不存在时失败
|
|
247
|
+
- 未知 `type`、未知 `oracleDriver` 或非法 `keepAliveSeconds` 会失败
|
|
248
|
+
- `exec` 缺少 `--db` 或 `--command` 会失败
|
|
249
|
+
- `meta columns` 缺少 `--table` 会失败
|
|
250
|
+
- 命中黑名单时失败,错误中包含 `黑名单拒绝执行命令`
|
|
251
|
+
- 违反只读模式时失败,错误中包含 `只读模式拒绝执行命令`
|
|
252
|
+
- 所有失败统一在 stderr 输出错误信息,退出码为 `1`
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"databases": {
|
|
3
|
+
"local-mysql": {
|
|
4
|
+
"type": "mysql",
|
|
5
|
+
"url": "mysql://test:test@127.0.0.1:3306/app",
|
|
6
|
+
"readonly": false,
|
|
7
|
+
"blacklist": ["drop", "truncate"],
|
|
8
|
+
"keepAliveSeconds": 180
|
|
9
|
+
},
|
|
10
|
+
"local-postgres": {
|
|
11
|
+
"type": "postgres",
|
|
12
|
+
"url": "postgres://test:test@127.0.0.1:5432/app",
|
|
13
|
+
"readonly": false,
|
|
14
|
+
"blacklist": ["drop", "truncate"],
|
|
15
|
+
"keepAliveSeconds": 180
|
|
16
|
+
},
|
|
17
|
+
"local-redis": {
|
|
18
|
+
"type": "redis",
|
|
19
|
+
"url": "redis://127.0.0.1:6379",
|
|
20
|
+
"readonly": false,
|
|
21
|
+
"blacklist": ["flushall", "flushdb"],
|
|
22
|
+
"keepAliveSeconds": 180
|
|
23
|
+
},
|
|
24
|
+
"local-mongodb": {
|
|
25
|
+
"type": "mongodb",
|
|
26
|
+
"url": "mongodb://test:test@127.0.0.1:27017/app?authSource=admin",
|
|
27
|
+
"database": "app",
|
|
28
|
+
"readonly": false,
|
|
29
|
+
"blacklist": ["drop", "dropDatabase", "deleteMany"],
|
|
30
|
+
"keepAliveSeconds": 180
|
|
31
|
+
},
|
|
32
|
+
"local-oracle": {
|
|
33
|
+
"type": "oracle",
|
|
34
|
+
"url": "oracle://test:test@127.0.0.1:1521/FREEPDB1",
|
|
35
|
+
"readonly": false,
|
|
36
|
+
"blacklist": ["drop", "truncate"],
|
|
37
|
+
"keepAliveSeconds": 180
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DatabaseAdapter, MetadataRequest, QueryResult } from "../types.js";
|
|
2
|
+
export declare abstract class BaseSqlAdapter implements DatabaseAdapter {
|
|
3
|
+
protected connected: boolean;
|
|
4
|
+
abstract connect(): Promise<void>;
|
|
5
|
+
abstract disconnect(): Promise<void>;
|
|
6
|
+
abstract execute(command: string): Promise<QueryResult>;
|
|
7
|
+
protected abstract listTables(): Promise<QueryResult>;
|
|
8
|
+
protected abstract listColumns(table: string): Promise<QueryResult>;
|
|
9
|
+
test(): Promise<void>;
|
|
10
|
+
metadata(request: MetadataRequest): Promise<QueryResult>;
|
|
11
|
+
protected testQuery(): string;
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class BaseSqlAdapter {
|
|
2
|
+
connected = false;
|
|
3
|
+
async test() {
|
|
4
|
+
await this.execute(this.testQuery());
|
|
5
|
+
}
|
|
6
|
+
async metadata(request) {
|
|
7
|
+
if (request.type === "tables") {
|
|
8
|
+
return this.listTables();
|
|
9
|
+
}
|
|
10
|
+
if (request.type === "columns") {
|
|
11
|
+
if (!request.table) {
|
|
12
|
+
throw new Error("columns 元信息查询必须提供 --table");
|
|
13
|
+
}
|
|
14
|
+
return this.listColumns(request.table);
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`当前数据库不支持元信息类型: ${request.type}`);
|
|
17
|
+
}
|
|
18
|
+
testQuery() {
|
|
19
|
+
return "select 1";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=base-sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-sql.js","sourceRoot":"","sources":["../../src/adapters/base-sql.ts"],"names":[],"mappings":"AAEA,MAAM,OAAgB,cAAc;IACxB,SAAS,GAAG,KAAK,CAAC;IAQ5B,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAES,SAAS;QACjB,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
|