@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.
Files changed (2) hide show
  1. package/CHANGELOG.md +376 -0
  2. 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.1.0",
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.1.0"
52
+ "@nifrajs/mcp": "5.2.0"
52
53
  },
53
54
  "repository": {
54
55
  "type": "git",