@nifrajs/mcp-db 5.1.0 → 5.2.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/CHANGELOG.md +376 -0
- package/package.json +4 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# @nifrajs/mcp-db
|
|
2
|
+
|
|
3
|
+
## 5.2.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9498cf8: The package ships its `CHANGELOG.md`, so the installed package has the notes for every version, as the GitHub release does. Before, the tarball held only the code, `README.md`, `LICENSE` and `package.json`.
|
|
8
|
+
- Updated dependencies [9498cf8]
|
|
9
|
+
- @nifrajs/mcp@5.2.0
|
|
10
|
+
|
|
11
|
+
## 5.1.0
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- abb4354: The package now ships the MIT `LICENSE` text, as every other @nifrajs package already did.
|
|
16
|
+
- Updated dependencies [abb4354]
|
|
17
|
+
- @nifrajs/mcp@5.1.0
|
|
18
|
+
|
|
19
|
+
## 5.0.0
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 5b17850: `run_query` no longer materializes oversized results before applying `maxResultBytes`. A text or blob cell longer than the budget arrives as `"<n bytes>"` instead of being copied out of SQLite, and rows stop being read once their cells pass the budget. Before, `SELECT zeroblob(2000000) FROM t` over 100 rows held about 2 GB and ran for over a minute before the byte cap applied. A result cut by the byte budget reports `total: null` unless `exactTotal` is on.
|
|
24
|
+
- e58690c: `explainPostgres` refuses a query that uses a masked column, as `queryPostgres` does, with `NIFRA_DB_COLUMN_REFUSED`, with or without `analyze`. Before, a plan's row counts and estimates for a filter such as `WHERE password_hash LIKE 'h%'` answered questions about the column. A plain `SELECT password_hash FROM users` is refused as well.
|
|
25
|
+
- 5377b66: `run_query` checks the tables the compiled statement opens, not only the names the SQL and the query plan use. A query is refused when it reads an unexposed table through a schema-qualified name beside a CTE of the same name, through any alias (non-ASCII ones included), through `x IN table`, or as a same-named table in a temp or attached schema of the connection.
|
|
26
|
+
- 437d3cd: `postgresRoleSql` and `nifra db-role` grant the role `SELECT` on each allowed schema only. On Postgres 14 and later, with nothing excluded, the role used to get `pg_read_all_data`, which reads every schema in the database whatever `schemas` named.
|
|
27
|
+
- cd07938: `run_query` refuses every query that opens a virtual table or a table-valued function, as documented, however the query names it. A `pragma_*` function or `dbstat` listed after a comma under an allowlisted alias used to pass the checks and return schema metadata of tables outside the allowlist.
|
|
28
|
+
- Updated dependencies [1af7543]
|
|
29
|
+
- @nifrajs/mcp@5.0.0
|
|
30
|
+
|
|
31
|
+
## 4.0.2
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- @nifrajs/mcp@4.0.2
|
|
36
|
+
|
|
37
|
+
## 4.0.1
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- @nifrajs/mcp@4.0.1
|
|
42
|
+
|
|
43
|
+
## 4.0.0
|
|
44
|
+
|
|
45
|
+
### Minor Changes
|
|
46
|
+
|
|
47
|
+
- d4d40a5: feat(mcp): `allowedHosts` DNS-rebinding guard
|
|
48
|
+
|
|
49
|
+
`createMcpServer()`, `respondMcpHttp()`, and `serveDatabaseAsMcp()` accept `allowedHosts`. A
|
|
50
|
+
request whose Host is not listed gets 403, with or without an Origin. Set it for servers on
|
|
51
|
+
localhost or a private network, where a DNS-rebound page presents a matching Origin. The check reads
|
|
52
|
+
the inbound `Host` header. Host names compare case-insensitively, an entry without a port matches any
|
|
53
|
+
port, and an entry with a port matches the effective port, so `localhost:80` admits
|
|
54
|
+
`http://localhost/`.
|
|
55
|
+
|
|
56
|
+
The same-origin default now accepts an `https:` Origin on an `http:` request URL (a TLS-terminating
|
|
57
|
+
proxy) and still rejects a downgrade.
|
|
58
|
+
|
|
59
|
+
- 37dff1d: The read-only SQLite engine is importable on its own from `@nifrajs/mcp-db/engine`.
|
|
60
|
+
|
|
61
|
+
- `openReadOnlySqlite` opens a file with the `readonly` flag and `PRAGMA query_only = ON`, and opens a WAL database that no writer has attached yet without making it writable.
|
|
62
|
+
- `querySqlite`, `explainSqlite` and `readSqliteSchema` take an `exclude` list. A query is one SELECT (or WITH ... SELECT), and every table its compiled statement opens must be exposed, so a view, a CTE or an alias cannot reach an excluded table.
|
|
63
|
+
- With a `redaction` option, a query that reads a column `redaction.column` matches is refused (`NIFRA_DB_COLUMN_REFUSED`), whether it selects the column under another name, wraps it in an expression, filters on it or reaches it through a view or an index. Results are capped by rows and bytes and JSON-safe (bigints beyond 2^53 as strings, blobs as `<n bytes>`).
|
|
64
|
+
- Every refusal is a `DbRefusal` with a stable `NIFRA_DB_*` code, a message, a fix and a docs anchor.
|
|
65
|
+
|
|
66
|
+
`serveDatabaseAsMcp` behaves as before.
|
|
67
|
+
|
|
68
|
+
- d4a79de: `@nifrajs/mcp-db/postgres` reads a development Postgres database on `Bun.SQL`, with the result shape and `NIFRA_DB_*` refusal codes of the SQLite engine.
|
|
69
|
+
|
|
70
|
+
- `parsePostgresUrl` and `connectPostgres` connect only to loopback, `*.localhost` or a unix socket unless `allowHosts` names the host, and start every session read-only.
|
|
71
|
+
- `queryPostgres` runs one statement through a tokenizer (one read-only statement, no row locks, no functions that reach outside a query), a `BEGIN READ ONLY` transaction with statement, lock and idle timeouts, a role gate (superusers and server-file or server-program roles are refused), an extension gate (dblink, postgres_fdw, file_fdw and untrusted languages, unless `allowExtensions` names them), a `DECLARE CURSOR` that the server accepts only for SELECT and VALUES, and a plan-level check that every relation, its parent tables and every catalog function in FROM are in `schemas` and outside `exclude`. With `redaction`, a column `redaction.column` matches that any plan expression uses, or a whole row holding one, is refused (`NIFRA_DB_COLUMN_REFUSED`).
|
|
72
|
+
- `explainPostgres` returns the JSON plan, and with `analyze` executes it inside the same transaction and timeout.
|
|
73
|
+
- `readPostgresSchema` lists the readable tables and views with columns, keys, indexes and row estimates, and leaves out an excluded table along with the views and child tables that read it.
|
|
74
|
+
- `postgresRoleSql` writes the SQL for a read-only login role, `pg_read_all_data` on Postgres 14 and later or `GRANT SELECT` per schema with a `REVOKE` per excluded table and partition, and runs none of it.
|
|
75
|
+
|
|
76
|
+
### Patch Changes
|
|
77
|
+
|
|
78
|
+
- 0f486f2: Closing a connection from `openReadOnlySqlite` releases the database file right away, instead of when its statements are garbage collected.
|
|
79
|
+
- Updated dependencies [d4d40a5]
|
|
80
|
+
- Updated dependencies [9ccf198]
|
|
81
|
+
- @nifrajs/mcp@4.0.0
|
|
82
|
+
|
|
83
|
+
## 3.5.0
|
|
84
|
+
|
|
85
|
+
### Patch Changes
|
|
86
|
+
|
|
87
|
+
- 6046984: Close fresh security and correctness gaps in table allowlists, ISR/cache behavior, streamed response capture, idempotency ownership, and canonical redirects.
|
|
88
|
+
- @nifrajs/mcp@3.5.0
|
|
89
|
+
|
|
90
|
+
## 3.4.0
|
|
91
|
+
|
|
92
|
+
### Patch Changes
|
|
93
|
+
|
|
94
|
+
- Updated dependencies [8d23613]
|
|
95
|
+
- Updated dependencies
|
|
96
|
+
- @nifrajs/mcp@3.4.0
|
|
97
|
+
|
|
98
|
+
## 3.3.0
|
|
99
|
+
|
|
100
|
+
### Patch Changes
|
|
101
|
+
|
|
102
|
+
- @nifrajs/mcp@3.3.0
|
|
103
|
+
|
|
104
|
+
## 3.2.0
|
|
105
|
+
|
|
106
|
+
### Patch Changes
|
|
107
|
+
|
|
108
|
+
- f34a050: Record the pending source changes for these packages in their release notes so fixed-version publishing does not omit their changelog entries.
|
|
109
|
+
- Updated dependencies [1a041a9]
|
|
110
|
+
- Updated dependencies [cefedc2]
|
|
111
|
+
- @nifrajs/mcp@3.2.0
|
|
112
|
+
|
|
113
|
+
## 3.1.0
|
|
114
|
+
|
|
115
|
+
### Patch Changes
|
|
116
|
+
|
|
117
|
+
- @nifrajs/mcp@3.1.0
|
|
118
|
+
|
|
119
|
+
## 3.0.0
|
|
120
|
+
|
|
121
|
+
### Patch Changes
|
|
122
|
+
|
|
123
|
+
- @nifrajs/mcp@3.0.0
|
|
124
|
+
|
|
125
|
+
## 2.14.1
|
|
126
|
+
|
|
127
|
+
### Patch Changes
|
|
128
|
+
|
|
129
|
+
- @nifrajs/mcp@2.14.1
|
|
130
|
+
|
|
131
|
+
## 2.14.0
|
|
132
|
+
|
|
133
|
+
### Patch Changes
|
|
134
|
+
|
|
135
|
+
- @nifrajs/mcp@2.14.0
|
|
136
|
+
|
|
137
|
+
## 2.13.0
|
|
138
|
+
|
|
139
|
+
### Patch Changes
|
|
140
|
+
|
|
141
|
+
- @nifrajs/mcp@2.13.0
|
|
142
|
+
|
|
143
|
+
## 2.12.1
|
|
144
|
+
|
|
145
|
+
### Patch Changes
|
|
146
|
+
|
|
147
|
+
- @nifrajs/mcp@2.12.1
|
|
148
|
+
|
|
149
|
+
## 2.12.0
|
|
150
|
+
|
|
151
|
+
### Minor Changes
|
|
152
|
+
|
|
153
|
+
- 81b1579: `run_query` now bounds what one call can cost. `queryTimeoutMs` (default 5 seconds) covers planning,
|
|
154
|
+
execution, and the optional count; `maxConcurrentQueries` (default 1) rejects calls that arrive
|
|
155
|
+
while the lane is busy. Row truncation no longer counts the full result to report a total: the
|
|
156
|
+
response carries `truncated: true` with `total: null`, and an exact total is opt-in per server via
|
|
157
|
+
`exactTotal`, which re-runs the query as a count.
|
|
158
|
+
|
|
159
|
+
Where the query runs depends on the database, and the difference is visible in the timeout it can
|
|
160
|
+
enforce. A file-backed database is reopened read-only in a worker that is spawned once, reused for
|
|
161
|
+
every call, and terminated when a deadline passes - so a runaway statement is stopped, and no call
|
|
162
|
+
copies the database. An in-memory database has no file to reopen and runs on the serving thread,
|
|
163
|
+
where a synchronous statement cannot be preempted; there the deadline still bounds the response but
|
|
164
|
+
is only observed once the statement returns. `SqliteDatabaseLike` gained an optional `filename` to
|
|
165
|
+
express that difference; any database shaped like it keeps working either way.
|
|
166
|
+
|
|
167
|
+
### Patch Changes
|
|
168
|
+
|
|
169
|
+
- 18c8301: The table allowlist is now checked against the SQL the query actually names, not only against SQLite's
|
|
170
|
+
query plan. A plan row reports the alias as its scan target, so `FROM "users" AS habits` planned as
|
|
171
|
+
`SCAN habits` and passed an allowlist that exposed `habits` but not `users`. A small tokenizer now
|
|
172
|
+
reads every relation after `FROM`/`JOIN` before the query runs - it handles all four SQLite identifier
|
|
173
|
+
quotings and the keyword-adjacent form (`FROM"users"`) a whitespace-anchored pattern cannot, drops
|
|
174
|
+
string literals and comments so text can never be read as SQL, and excludes CTE names. The plan check
|
|
175
|
+
still runs afterwards, and now resolves a schema-qualified `SCAN main.habits` to `habits` rather than
|
|
176
|
+
rejecting it as a table named `main`.
|
|
177
|
+
|
|
178
|
+
`maxResultBytes` is enforced on the encoded UTF-8 byte length of the whole payload, envelope included,
|
|
179
|
+
rather than on the JS string length of the rows alone - a multi-byte result could exceed the cap it
|
|
180
|
+
had just been measured against. A payload still over the cap after halving down to zero rows is an
|
|
181
|
+
error rather than an oversized response.
|
|
182
|
+
|
|
183
|
+
Authorization moves onto `@nifrajs/mcp`'s new `authorizeMessage` seam, so a `run_query` call is
|
|
184
|
+
authorized from the message the server already parsed instead of from a second `request.clone().json()`
|
|
185
|
+
read of the body.
|
|
186
|
+
|
|
187
|
+
- Updated dependencies [cb04de8]
|
|
188
|
+
- Updated dependencies [f3cc02e]
|
|
189
|
+
- Updated dependencies [e2d1939]
|
|
190
|
+
- @nifrajs/mcp@2.12.0
|
|
191
|
+
|
|
192
|
+
## 2.11.0
|
|
193
|
+
|
|
194
|
+
### Patch Changes
|
|
195
|
+
|
|
196
|
+
- @nifrajs/mcp@2.11.0
|
|
197
|
+
|
|
198
|
+
## 2.10.0
|
|
199
|
+
|
|
200
|
+
### Patch Changes
|
|
201
|
+
|
|
202
|
+
- @nifrajs/mcp@2.10.0
|
|
203
|
+
|
|
204
|
+
## 2.9.1
|
|
205
|
+
|
|
206
|
+
### Patch Changes
|
|
207
|
+
|
|
208
|
+
- @nifrajs/mcp@2.9.1
|
|
209
|
+
|
|
210
|
+
## 2.9.0
|
|
211
|
+
|
|
212
|
+
### Patch Changes
|
|
213
|
+
|
|
214
|
+
- @nifrajs/mcp@2.9.0
|
|
215
|
+
|
|
216
|
+
## 2.8.2
|
|
217
|
+
|
|
218
|
+
### Patch Changes
|
|
219
|
+
|
|
220
|
+
- f7d68e8: Numeric limit options (body/payload byte caps, TTLs, cache sizes, concurrency, ISR revalidate windows) are now validated at construction and throw a `RangeError` on non-finite or out-of-range values instead of silently disabling the bound - a `NaN` cap previously made `size > max` comparisons fail open. JWT `requiredClaims` now checks own properties only, so inherited names like `toString` no longer satisfy a required claim. `@nifrajs/mcp-db` gates multi-statement input with a real tokenizer, bounds `run_query` materialization to `maxRows + 1` via a wrapping subquery, and skips SQLite planner pseudo-nodes when verifying the table allowlist. `nifra scaffold` refuses to write through symlinked route directories.
|
|
221
|
+
- Updated dependencies [f7d68e8]
|
|
222
|
+
- @nifrajs/mcp@2.8.2
|
|
223
|
+
|
|
224
|
+
## 2.8.1
|
|
225
|
+
|
|
226
|
+
### Patch Changes
|
|
227
|
+
|
|
228
|
+
- @nifrajs/mcp@2.8.1
|
|
229
|
+
|
|
230
|
+
## 2.8.0
|
|
231
|
+
|
|
232
|
+
### Patch Changes
|
|
233
|
+
|
|
234
|
+
- @nifrajs/mcp@2.8.0
|
|
235
|
+
|
|
236
|
+
## 2.7.1
|
|
237
|
+
|
|
238
|
+
### Patch Changes
|
|
239
|
+
|
|
240
|
+
- @nifrajs/mcp@2.7.1
|
|
241
|
+
|
|
242
|
+
## 2.7.0
|
|
243
|
+
|
|
244
|
+
### Patch Changes
|
|
245
|
+
|
|
246
|
+
- @nifrajs/mcp@2.7.0
|
|
247
|
+
|
|
248
|
+
## 2.6.1
|
|
249
|
+
|
|
250
|
+
### Patch Changes
|
|
251
|
+
|
|
252
|
+
- @nifrajs/mcp@2.6.1
|
|
253
|
+
|
|
254
|
+
## 2.6.0
|
|
255
|
+
|
|
256
|
+
### Patch Changes
|
|
257
|
+
|
|
258
|
+
- Updated dependencies [10fb70c]
|
|
259
|
+
- @nifrajs/mcp@2.6.0
|
|
260
|
+
|
|
261
|
+
## 2.5.0
|
|
262
|
+
|
|
263
|
+
### Patch Changes
|
|
264
|
+
|
|
265
|
+
- Updated dependencies [3731c69]
|
|
266
|
+
- Updated dependencies [0740f77]
|
|
267
|
+
- @nifrajs/mcp@2.5.0
|
|
268
|
+
|
|
269
|
+
## 2.4.0
|
|
270
|
+
|
|
271
|
+
### Patch Changes
|
|
272
|
+
|
|
273
|
+
- @nifrajs/mcp@2.4.0
|
|
274
|
+
|
|
275
|
+
## 2.3.0
|
|
276
|
+
|
|
277
|
+
### Patch Changes
|
|
278
|
+
|
|
279
|
+
- ea0a27f: A durable table prefix cannot collide after PostgreSQL truncates it.
|
|
280
|
+
|
|
281
|
+
**Breaking for prefixes longer than 45 characters**, which now fail at construction rather than later.
|
|
282
|
+
PostgreSQL truncates identifiers to 63 bytes, and this adapter appends up to `_records_reconcile` (18)
|
|
283
|
+
to the prefix. Two distinct prefixes long enough to be cut short became one table name, silently
|
|
284
|
+
sharing state between what the caller believed were separate deployments. The accepted length now
|
|
285
|
+
reserves the longest suffix, so an accepted prefix survives truncation intact.
|
|
286
|
+
|
|
287
|
+
Both adapters also assemble their statements through a tagged template that validates every
|
|
288
|
+
substitution as an identifier at the boundary, so the check is at the seam rather than trusted from a
|
|
289
|
+
caller several frames up.
|
|
290
|
+
|
|
291
|
+
- @nifrajs/mcp@2.3.0
|
|
292
|
+
|
|
293
|
+
## 2.2.0
|
|
294
|
+
|
|
295
|
+
### Patch Changes
|
|
296
|
+
|
|
297
|
+
- @nifrajs/mcp@2.2.0
|
|
298
|
+
|
|
299
|
+
## 2.1.0
|
|
300
|
+
|
|
301
|
+
### Patch Changes
|
|
302
|
+
|
|
303
|
+
- @nifrajs/mcp@2.1.0
|
|
304
|
+
|
|
305
|
+
## 2.0.0
|
|
306
|
+
|
|
307
|
+
### Patch Changes
|
|
308
|
+
|
|
309
|
+
- Updated dependencies [d91a45b]
|
|
310
|
+
- Updated dependencies [202e758]
|
|
311
|
+
- @nifrajs/mcp@2.0.0
|
|
312
|
+
|
|
313
|
+
## 1.13.0
|
|
314
|
+
|
|
315
|
+
### Patch Changes
|
|
316
|
+
|
|
317
|
+
- @nifrajs/mcp@1.13.0
|
|
318
|
+
|
|
319
|
+
## 1.12.0
|
|
320
|
+
|
|
321
|
+
### Patch Changes
|
|
322
|
+
|
|
323
|
+
- @nifrajs/mcp@1.12.0
|
|
324
|
+
|
|
325
|
+
## 1.11.0
|
|
326
|
+
|
|
327
|
+
### Patch Changes
|
|
328
|
+
|
|
329
|
+
- @nifrajs/mcp@1.11.0
|
|
330
|
+
|
|
331
|
+
## 1.10.0
|
|
332
|
+
|
|
333
|
+
### Patch Changes
|
|
334
|
+
|
|
335
|
+
- @nifrajs/mcp@1.10.0
|
|
336
|
+
|
|
337
|
+
## 1.9.1
|
|
338
|
+
|
|
339
|
+
### Patch Changes
|
|
340
|
+
|
|
341
|
+
- Updated dependencies [3eb27ae]
|
|
342
|
+
- @nifrajs/mcp@1.9.1
|
|
343
|
+
|
|
344
|
+
## 1.9.0
|
|
345
|
+
|
|
346
|
+
### Patch Changes
|
|
347
|
+
|
|
348
|
+
- @nifrajs/mcp@1.9.0
|
|
349
|
+
|
|
350
|
+
## 1.8.0
|
|
351
|
+
|
|
352
|
+
### Patch Changes
|
|
353
|
+
|
|
354
|
+
- @nifrajs/mcp@1.8.0
|
|
355
|
+
|
|
356
|
+
## 1.7.0
|
|
357
|
+
|
|
358
|
+
### Patch Changes
|
|
359
|
+
|
|
360
|
+
- @nifrajs/mcp@1.7.0
|
|
361
|
+
|
|
362
|
+
## 1.6.0
|
|
363
|
+
|
|
364
|
+
### Patch Changes
|
|
365
|
+
|
|
366
|
+
- @nifrajs/mcp@1.6.0
|
|
367
|
+
|
|
368
|
+
## 1.5.0
|
|
369
|
+
|
|
370
|
+
### Minor Changes
|
|
371
|
+
|
|
372
|
+
- 79ac481: Two new agent-native packages. `@nifrajs/prompt`: type-safe prompts over any LLM provider - bind an instruction to input/output Standard Schemas, hand the output schema to the provider as its structured-output format, and get a validated, typed result (provider-neutral `complete` fn, markdown-fence tolerance, bounded `heal` retries). `@nifrajs/mcp-db`: serve a SQLite database as a fail-closed MCP server - allowlisted `list_tables`/`describe_table` by default; opt-in `run_query` requires an authorize hook and enforces read-only in layers (engine `PRAGMA query_only`, single-statement + SELECT-only gates, `EXPLAIN QUERY PLAN` allowlist verification, row/byte caps with truncation markers).
|
|
373
|
+
|
|
374
|
+
### Patch Changes
|
|
375
|
+
|
|
376
|
+
- @nifrajs/mcp@1.5.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/mcp-db",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Serve a SQLite database as a fail-closed MCP server - allowlisted schema tools by default, opt-in read-only queries with plan verification.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
},
|
|
38
38
|
"files": [
|
|
39
39
|
"dist",
|
|
40
|
-
"src"
|
|
40
|
+
"src",
|
|
41
|
+
"CHANGELOG.md"
|
|
41
42
|
],
|
|
42
43
|
"sideEffects": false,
|
|
43
44
|
"scripts": {
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
"access": "public"
|
|
49
50
|
},
|
|
50
51
|
"dependencies": {
|
|
51
|
-
"@nifrajs/mcp": "5.
|
|
52
|
+
"@nifrajs/mcp": "5.2.0"
|
|
52
53
|
},
|
|
53
54
|
"repository": {
|
|
54
55
|
"type": "git",
|