db-mcp 2.0.0 → 3.0.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 +96 -91
- package/dist/.tsbuildinfo +1 -0
- package/dist/adapters/database-adapter.d.ts +173 -0
- package/dist/adapters/database-adapter.d.ts.map +1 -0
- package/dist/adapters/query-validation.d.ts +20 -0
- package/dist/adapters/query-validation.d.ts.map +1 -0
- package/dist/adapters/registration/index.d.ts +4 -0
- package/dist/adapters/registration/index.d.ts.map +1 -0
- package/dist/adapters/registration/prompts.d.ts +7 -0
- package/dist/adapters/registration/prompts.d.ts.map +1 -0
- package/dist/adapters/registration/resources.d.ts +7 -0
- package/dist/adapters/registration/resources.d.ts.map +1 -0
- package/dist/adapters/registration/tools.d.ts +9 -0
- package/dist/adapters/registration/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite/index.d.ts +9 -0
- package/dist/adapters/sqlite/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/json-utils.d.ts +100 -0
- package/dist/adapters/sqlite/json-utils.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/analysis.d.ts +23 -0
- package/dist/adapters/sqlite/prompts/analysis.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/index.d.ts +16 -0
- package/dist/adapters/sqlite/prompts/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/query.d.ts +19 -0
- package/dist/adapters/sqlite/prompts/query.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/schema.d.ts +20 -0
- package/dist/adapters/sqlite/prompts/schema.d.ts.map +1 -0
- package/dist/adapters/sqlite/query-executor.d.ts +38 -0
- package/dist/adapters/sqlite/query-executor.d.ts.map +1 -0
- package/dist/adapters/sqlite/resources.d.ts +13 -0
- package/dist/adapters/sqlite/resources.d.ts.map +1 -0
- package/dist/adapters/sqlite/schema-manager.d.ts +69 -0
- package/dist/adapters/sqlite/schema-manager.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/admin.d.ts +459 -0
- package/dist/adapters/sqlite/schemas/admin.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/codemode.d.ts +30 -0
- package/dist/adapters/sqlite/schemas/codemode.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/common.d.ts +9 -0
- package/dist/adapters/sqlite/schemas/common.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/core.d.ts +530 -0
- package/dist/adapters/sqlite/schemas/core.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/error-mixin.d.ts +10 -0
- package/dist/adapters/sqlite/schemas/error-mixin.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/fts.d.ts +106 -0
- package/dist/adapters/sqlite/schemas/fts.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/geo.d.ts +135 -0
- package/dist/adapters/sqlite/schemas/geo.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/index.d.ts +23 -0
- package/dist/adapters/sqlite/schemas/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/introspection.d.ts +583 -0
- package/dist/adapters/sqlite/schemas/introspection.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/json.d.ts +849 -0
- package/dist/adapters/sqlite/schemas/json.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/migration.d.ts +220 -0
- package/dist/adapters/sqlite/schemas/migration.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/native.d.ts +235 -0
- package/dist/adapters/sqlite/schemas/native.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/server.d.ts +13 -0
- package/dist/adapters/sqlite/schemas/server.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/spatialite.d.ts +114 -0
- package/dist/adapters/sqlite/schemas/spatialite.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/stats.d.ts +780 -0
- package/dist/adapters/sqlite/schemas/stats.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/text.d.ts +570 -0
- package/dist/adapters/sqlite/schemas/text.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/vector.d.ts +252 -0
- package/dist/adapters/sqlite/schemas/vector.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/virtual.d.ts +257 -0
- package/dist/adapters/sqlite/schemas/virtual.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/where.d.ts +20 -0
- package/dist/adapters/sqlite/schemas/where.d.ts.map +1 -0
- package/dist/adapters/sqlite/sqlite-adapter/lifecycle.d.ts +13 -0
- package/dist/adapters/sqlite/sqlite-adapter/lifecycle.d.ts.map +1 -0
- package/dist/adapters/sqlite/sqlite-adapter/schema.d.ts +7 -0
- package/dist/adapters/sqlite/sqlite-adapter/schema.d.ts.map +1 -0
- package/dist/adapters/sqlite/sqlite-adapter.d.ts +138 -0
- package/dist/adapters/sqlite/sqlite-adapter.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/analyze.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/analyze.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/create.d.ts +11 -0
- package/dist/adapters/sqlite/tools/admin/backup/create.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/dump.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/dump.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/index.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/integrity.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/integrity.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/optimize.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/optimize.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/restore.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/restore.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/helpers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/admin/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/admin/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/pragma.d.ts +37 -0
- package/dist/adapters/sqlite/tools/admin/pragma.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/reindex.d.ts +10 -0
- package/dist/adapters/sqlite/tools/admin/reindex.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/verify.d.ts +13 -0
- package/dist/adapters/sqlite/tools/admin/verify.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/wal.d.ts +10 -0
- package/dist/adapters/sqlite/tools/admin/wal.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/codemode.d.ts +22 -0
- package/dist/adapters/sqlite/tools/codemode.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/column-validation.d.ts +26 -0
- package/dist/adapters/sqlite/tools/column-validation.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/alter-table.d.ts +11 -0
- package/dist/adapters/sqlite/tools/core/alter-table.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/constraints.d.ts +10 -0
- package/dist/adapters/sqlite/tools/core/constraints.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/convenience-helpers.d.ts +20 -0
- package/dist/adapters/sqlite/tools/core/convenience-helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/convenience-schemas.d.ts +20 -0
- package/dist/adapters/sqlite/tools/core/convenience-schemas.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/convenience.d.ts +29 -0
- package/dist/adapters/sqlite/tools/core/convenience.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/datetime.d.ts +11 -0
- package/dist/adapters/sqlite/tools/core/datetime.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/index.d.ts +14 -0
- package/dist/adapters/sqlite/tools/core/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/indexes.d.ts +20 -0
- package/dist/adapters/sqlite/tools/core/indexes.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/queries.d.ts +16 -0
- package/dist/adapters/sqlite/tools/core/queries.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/tables.d.ts +37 -0
- package/dist/adapters/sqlite/tools/core/tables.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/triggers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/core/triggers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/fts.d.ts +13 -0
- package/dist/adapters/sqlite/tools/fts.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/geo.d.ts +14 -0
- package/dist/adapters/sqlite/tools/geo.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/index.d.ts +33 -0
- package/dist/adapters/sqlite/tools/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/constraints.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/constraints.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/diff.d.ts +11 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/diff.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/risks.d.ts +9 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/risks.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/snapshot.d.ts +40 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/snapshot.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/index.d.ts +9 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/indexes.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/indexes.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/query-plan.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/query-plan.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/storage.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/storage.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/graph/helpers.d.ts +44 -0
- package/dist/adapters/sqlite/tools/introspection/graph/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/graph/index.d.ts +9 -0
- package/dist/adapters/sqlite/tools/introspection/graph/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/graph/tools.d.ts +12 -0
- package/dist/adapters/sqlite/tools/introspection/graph/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/index.d.ts +17 -0
- package/dist/adapters/sqlite/tools/introspection/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/helpers.d.ts +21 -0
- package/dist/adapters/sqlite/tools/json-helpers/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/index.d.ts +17 -0
- package/dist/adapters/sqlite/tools/json-helpers/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/read.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-helpers/read.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/write.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-helpers/write.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/crud.d.ts +39 -0
- package/dist/adapters/sqlite/tools/json-operations/crud.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/diff.d.ts +11 -0
- package/dist/adapters/sqlite/tools/json-operations/diff.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/helpers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/json-operations/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/json-operations/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/query.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-operations/query.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/security.d.ts +19 -0
- package/dist/adapters/sqlite/tools/json-operations/security.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/transform.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-operations/transform.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/helpers.d.ts +34 -0
- package/dist/adapters/sqlite/tools/migration/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/index.d.ts +15 -0
- package/dist/adapters/sqlite/tools/migration/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/apply.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/apply.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/history.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/history.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/index.d.ts +7 -0
- package/dist/adapters/sqlite/tools/migration/tracking/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/init.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/init.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/record.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/record.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/rollback.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/rollback.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/status.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/status.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/advanced.d.ts +28 -0
- package/dist/adapters/sqlite/tools/stats/advanced.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/anomaly-detection.d.ts +22 -0
- package/dist/adapters/sqlite/tools/stats/anomaly-detection.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/basic.d.ts +32 -0
- package/dist/adapters/sqlite/tools/stats/basic.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/helpers.d.ts +27 -0
- package/dist/adapters/sqlite/tools/stats/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/index.d.ts +12 -0
- package/dist/adapters/sqlite/tools/stats/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/hypothesis.d.ts +7 -0
- package/dist/adapters/sqlite/tools/stats/inference/hypothesis.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/index.d.ts +4 -0
- package/dist/adapters/sqlite/tools/stats/inference/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/outlier.d.ts +7 -0
- package/dist/adapters/sqlite/tools/stats/inference/outlier.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/regression.d.ts +7 -0
- package/dist/adapters/sqlite/tools/stats/inference/regression.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/math-helpers.d.ts +17 -0
- package/dist/adapters/sqlite/tools/stats/math-helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/schema-risks.d.ts +15 -0
- package/dist/adapters/sqlite/tools/stats/schema-risks.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/formatting.d.ts +48 -0
- package/dist/adapters/sqlite/tools/text/formatting.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/helpers.d.ts +22 -0
- package/dist/adapters/sqlite/tools/text/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/text/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/regex.d.ts +21 -0
- package/dist/adapters/sqlite/tools/text/regex.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/search.d.ts +17 -0
- package/dist/adapters/sqlite/tools/text/search.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/sentiment.d.ts +13 -0
- package/dist/adapters/sqlite/tools/text/sentiment.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/validate.d.ts +11 -0
- package/dist/adapters/sqlite/tools/text/validate.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/helpers.d.ts +11 -0
- package/dist/adapters/sqlite/tools/vector/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/index.d.ts +14 -0
- package/dist/adapters/sqlite/tools/vector/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/metadata.d.ts +28 -0
- package/dist/adapters/sqlite/tools/vector/metadata.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/search.d.ts +16 -0
- package/dist/adapters/sqlite/tools/vector/search.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/storage.d.ts +24 -0
- package/dist/adapters/sqlite/tools/vector/storage.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/tools.d.ts +9 -0
- package/dist/adapters/sqlite/tools/vector/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/analysis.d.ts +24 -0
- package/dist/adapters/sqlite/tools/virtual/analysis.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/extensions.d.ts +13 -0
- package/dist/adapters/sqlite/tools/virtual/extensions.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/helpers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/virtual/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/virtual/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/views.d.ts +21 -0
- package/dist/adapters/sqlite/tools/virtual/views.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/analyze-csv.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/analyze-csv.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/csv.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/csv.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/drop.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/drop.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/index.d.ts +6 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/info.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/info.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/list.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/list.d.ts.map +1 -0
- package/dist/adapters/sqlite/types.d.ts +89 -0
- package/dist/adapters/sqlite/types.d.ts.map +1 -0
- package/dist/adapters/sqlite-helpers.d.ts +51 -0
- package/dist/adapters/sqlite-helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/extensions.d.ts +17 -0
- package/dist/adapters/sqlite-native/extensions.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/index.d.ts +11 -0
- package/dist/adapters/sqlite-native/index.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/native-query-executor.d.ts +24 -0
- package/dist/adapters/sqlite-native/native-query-executor.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/native-sqlite-adapter.d.ts +160 -0
- package/dist/adapters/sqlite-native/native-sqlite-adapter.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/registration/index.d.ts +12 -0
- package/dist/adapters/sqlite-native/registration/index.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/analysis.d.ts +23 -0
- package/dist/adapters/sqlite-native/tools/spatialite/analysis.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/index.d.ts +15 -0
- package/dist/adapters/sqlite-native/tools/spatialite/index.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/loader.d.ts +22 -0
- package/dist/adapters/sqlite-native/tools/spatialite/loader.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/schemas.d.ts +78 -0
- package/dist/adapters/sqlite-native/tools/spatialite/schemas.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/tools.d.ts +30 -0
- package/dist/adapters/sqlite-native/tools/spatialite/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/transactions.d.ts +12 -0
- package/dist/adapters/sqlite-native/tools/transactions.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/window.d.ts +7 -0
- package/dist/adapters/sqlite-native/tools/window.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/transaction-methods.d.ts +36 -0
- package/dist/adapters/sqlite-native/transaction-methods.d.ts.map +1 -0
- package/dist/audit/backup-manager.d.ts +90 -0
- package/dist/audit/backup-manager.d.ts.map +1 -0
- package/dist/audit/index.d.ts +11 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/interceptor.d.ts +54 -0
- package/dist/audit/interceptor.d.ts.map +1 -0
- package/dist/audit/logger.d.ts +62 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/types.d.ts +112 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/auth/auth-context.d.ts +28 -0
- package/dist/auth/auth-context.d.ts.map +1 -0
- package/dist/auth/authorization-server-discovery.d.ts +90 -0
- package/dist/auth/authorization-server-discovery.d.ts.map +1 -0
- package/dist/auth/errors.d.ts +74 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/middleware/core.d.ts +22 -0
- package/dist/auth/middleware/core.d.ts.map +1 -0
- package/dist/auth/middleware/express-auth.d.ts +13 -0
- package/dist/auth/middleware/express-auth.d.ts.map +1 -0
- package/dist/auth/middleware/express-scopes.d.ts +6 -0
- package/dist/auth/middleware/express-scopes.d.ts.map +1 -0
- package/dist/auth/middleware/extraction.d.ts +2 -0
- package/dist/auth/middleware/extraction.d.ts.map +1 -0
- package/dist/auth/middleware/index.d.ts +5 -0
- package/dist/auth/middleware/index.d.ts.map +1 -0
- package/dist/auth/oauth-resource-server.d.ts +74 -0
- package/dist/auth/oauth-resource-server.d.ts.map +1 -0
- package/dist/auth/scope-map.d.ts +24 -0
- package/dist/auth/scope-map.d.ts.map +1 -0
- package/dist/auth/scopes/constants.d.ts +40 -0
- package/dist/auth/scopes/constants.d.ts.map +1 -0
- package/dist/auth/scopes/display.d.ts +5 -0
- package/dist/auth/scopes/display.d.ts.map +1 -0
- package/dist/auth/scopes/enforcement.d.ts +27 -0
- package/dist/auth/scopes/enforcement.d.ts.map +1 -0
- package/dist/auth/scopes/index.d.ts +6 -0
- package/dist/auth/scopes/index.d.ts.map +1 -0
- package/dist/auth/scopes/mapping.d.ts +39 -0
- package/dist/auth/scopes/mapping.d.ts.map +1 -0
- package/dist/auth/scopes/validation.d.ts +27 -0
- package/dist/auth/scopes/validation.d.ts.map +1 -0
- package/dist/auth/token-validator.d.ts +63 -0
- package/dist/auth/token-validator.d.ts.map +1 -0
- package/dist/auth/transport-agnostic.d.ts +11 -0
- package/dist/auth/transport-agnostic.d.ts.map +1 -0
- package/dist/auth/types.d.ts +257 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/{chunk-WBER5YY4.js → chunk-37G4DLL6.js} +1010 -409
- package/dist/chunk-E5IESRTK.js +489 -0
- package/dist/{chunk-645ZEFLA.js → chunk-L552U3QS.js} +887 -309
- package/dist/{chunk-5Y42NPBP.js → chunk-NV34JSQM.js} +4656 -1829
- package/dist/{chunk-Z7C2TM4L.js → chunk-W5WQVNVX.js} +169 -57
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +47 -26
- package/dist/codemode/api-constants.d.ts +40 -0
- package/dist/codemode/api-constants.d.ts.map +1 -0
- package/dist/codemode/api.d.ts +70 -0
- package/dist/codemode/api.d.ts.map +1 -0
- package/dist/codemode/auto-return.d.ts +25 -0
- package/dist/codemode/auto-return.d.ts.map +1 -0
- package/dist/codemode/index.d.ts +12 -0
- package/dist/codemode/index.d.ts.map +1 -0
- package/dist/codemode/sandbox-factory.d.ts +72 -0
- package/dist/codemode/sandbox-factory.d.ts.map +1 -0
- package/dist/codemode/sandbox.d.ts +54 -0
- package/dist/codemode/sandbox.d.ts.map +1 -0
- package/dist/codemode/security.d.ts +45 -0
- package/dist/codemode/security.d.ts.map +1 -0
- package/dist/codemode/types.d.ts +167 -0
- package/dist/codemode/types.d.ts.map +1 -0
- package/dist/constants/server-instructions.d.ts +22 -0
- package/dist/constants/server-instructions.d.ts.map +1 -0
- package/dist/filtering/tool-constants.d.ts +45 -0
- package/dist/filtering/tool-constants.d.ts.map +1 -0
- package/dist/filtering/tool-filter.d.ts +82 -0
- package/dist/filtering/tool-filter.d.ts.map +1 -0
- package/dist/{http-6KF4ULDI.js → http-HWTUVFIA.js} +498 -391
- package/dist/index.d.ts +9 -1065
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -6
- package/dist/server/mcp-server.d.ts +66 -0
- package/dist/server/mcp-server.d.ts.map +1 -0
- package/dist/server/registration/audit-tools.d.ts +13 -0
- package/dist/server/registration/audit-tools.d.ts.map +1 -0
- package/dist/server/registration/built-in-tools.d.ts +8 -0
- package/dist/server/registration/built-in-tools.d.ts.map +1 -0
- package/dist/server/registration/help-resources.d.ts +7 -0
- package/dist/server/registration/help-resources.d.ts.map +1 -0
- package/dist/server/registration/index.d.ts +4 -0
- package/dist/server/registration/index.d.ts.map +1 -0
- package/dist/{sqlite-U5KSYQXK.js → sqlite-TB56Z7G3.js} +61 -17
- package/dist/{sqlite-native-JXMCFQBA.js → sqlite-native-IF75BB3O.js} +459 -254
- package/dist/transports/http/index.d.ts +8 -0
- package/dist/transports/http/index.d.ts.map +1 -0
- package/dist/transports/http/middleware.d.ts +25 -0
- package/dist/transports/http/middleware.d.ts.map +1 -0
- package/dist/transports/http/oauth.d.ts +24 -0
- package/dist/transports/http/oauth.d.ts.map +1 -0
- package/dist/transports/http/session.d.ts +2 -0
- package/dist/transports/http/session.d.ts.map +1 -0
- package/dist/transports/http/sessions/index.d.ts +4 -0
- package/dist/transports/http/sessions/index.d.ts.map +1 -0
- package/dist/transports/http/sessions/legacy-sse.d.ts +6 -0
- package/dist/transports/http/sessions/legacy-sse.d.ts.map +1 -0
- package/dist/transports/http/sessions/mutex.d.ts +6 -0
- package/dist/transports/http/sessions/mutex.d.ts.map +1 -0
- package/dist/transports/http/sessions/stateful.d.ts +12 -0
- package/dist/transports/http/sessions/stateful.d.ts.map +1 -0
- package/dist/transports/http/sessions/stateless.d.ts +6 -0
- package/dist/transports/http/sessions/stateless.d.ts.map +1 -0
- package/dist/transports/http/transport.d.ts +65 -0
- package/dist/transports/http/transport.d.ts.map +1 -0
- package/dist/transports/http/type-adapters.d.ts +20 -0
- package/dist/transports/http/type-adapters.d.ts.map +1 -0
- package/dist/transports/http/types.d.ts +120 -0
- package/dist/transports/http/types.d.ts.map +1 -0
- package/dist/types/adapter.d.ts +138 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/auth.d.ts +79 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/database.d.ts +100 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/filtering.d.ts +41 -0
- package/dist/types/filtering.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/server.d.ts +48 -0
- package/dist/types/server.d.ts.map +1 -0
- package/dist/utils/annotations.d.ts +62 -0
- package/dist/utils/annotations.d.ts.map +1 -0
- package/dist/utils/errors/base.d.ts +33 -0
- package/dist/utils/errors/base.d.ts.map +1 -0
- package/dist/utils/errors/categories.d.ts +41 -0
- package/dist/utils/errors/categories.d.ts.map +1 -0
- package/dist/utils/errors/classes.d.ts +124 -0
- package/dist/utils/errors/classes.d.ts.map +1 -0
- package/dist/utils/errors/error-response-fields.d.ts +24 -0
- package/dist/utils/errors/error-response-fields.d.ts.map +1 -0
- package/dist/utils/errors/format.d.ts +74 -0
- package/dist/utils/errors/format.d.ts.map +1 -0
- package/dist/utils/errors/index.d.ts +11 -0
- package/dist/utils/errors/index.d.ts.map +1 -0
- package/dist/utils/errors/suggestions.d.ts +16 -0
- package/dist/utils/errors/suggestions.d.ts.map +1 -0
- package/dist/utils/icons.d.ts +19 -0
- package/dist/utils/icons.d.ts.map +1 -0
- package/dist/utils/identifiers.d.ts +121 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/insights-manager.d.ts +39 -0
- package/dist/utils/insights-manager.d.ts.map +1 -0
- package/dist/utils/logger/error-codes.d.ts +48 -0
- package/dist/utils/logger/error-codes.d.ts.map +1 -0
- package/dist/utils/logger/index.d.ts +22 -0
- package/dist/utils/logger/index.d.ts.map +1 -0
- package/dist/utils/logger/logger.d.ts +94 -0
- package/dist/utils/logger/logger.d.ts.map +1 -0
- package/dist/utils/logger/module-logger.d.ts +28 -0
- package/dist/utils/logger/module-logger.d.ts.map +1 -0
- package/dist/utils/logger/types.d.ts +36 -0
- package/dist/utils/logger/types.d.ts.map +1 -0
- package/dist/utils/progress-utils.d.ts +54 -0
- package/dist/utils/progress-utils.d.ts.map +1 -0
- package/dist/utils/redaction.d.ts +4 -0
- package/dist/utils/redaction.d.ts.map +1 -0
- package/dist/utils/resource-annotations.d.ts +36 -0
- package/dist/utils/resource-annotations.d.ts.map +1 -0
- package/dist/utils/validate-json-path.d.ts +43 -0
- package/dist/utils/validate-json-path.d.ts.map +1 -0
- package/dist/utils/validate-path.d.ts +37 -0
- package/dist/utils/validate-path.d.ts.map +1 -0
- package/dist/utils/where-clause.d.ts +42 -0
- package/dist/utils/where-clause.d.ts.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +26 -13
- package/.gitattributes +0 -2
- package/.gitleaks.toml +0 -9
- package/.trivyignore +0 -8
- package/dist/chunk-OKOVZ5QE.js +0 -28
- package/dist/chunk-SFJQCNG7.js +0 -131
- package/dist/chunk-VIDSICEL.js +0 -85
- package/dist/chunk-X3MUUOWM.js +0 -152
- package/dist/worker-script.d.ts +0 -2
- package/dist/worker-script.js +0 -150
- package/logs/.gitkeep +0 -1
- package/mcp-config-example.json +0 -83
- package/playwright.config.ts +0 -101
- package/scripts/generate-server-instructions.ts +0 -111
- package/scripts/update-badges.ts +0 -99
- package/server.json +0 -54
- package/test-server/README.md +0 -115
- package/test-server/code-map.md +0 -421
- package/test-server/fixtures/sample.csv +0 -6
- package/test-server/reset-database.ps1 +0 -415
- package/test-server/sample.csv +0 -11
- package/test-server/scripts/README.md +0 -27
- package/test-server/scripts/test-help-resources.mjs +0 -245
- package/test-server/scripts/test-prompts.mjs +0 -251
- package/test-server/scripts/test-tool-annotations.mjs +0 -162
- package/test-server/test-advanced/README.md +0 -70
- package/test-server/test-advanced/test-codemode-advanced-admin.md +0 -174
- package/test-server/test-advanced/test-codemode-advanced-core.md +0 -193
- package/test-server/test-advanced/test-codemode-advanced-geo.md +0 -157
- package/test-server/test-advanced/test-codemode-advanced-introspection.md +0 -171
- package/test-server/test-advanced/test-codemode-advanced-json.md +0 -169
- package/test-server/test-advanced/test-codemode-advanced-migration.md +0 -160
- package/test-server/test-advanced/test-codemode-advanced-stats.md +0 -185
- package/test-server/test-advanced/test-codemode-advanced-text.md +0 -183
- package/test-server/test-advanced/test-codemode-advanced-transactions.md +0 -136
- package/test-server/test-advanced/test-codemode-advanced-vector.md +0 -141
- package/test-server/test-codemode/README.md +0 -121
- package/test-server/test-codemode/test-codemode-admin.md +0 -223
- package/test-server/test-codemode/test-codemode-core.md +0 -286
- package/test-server/test-codemode/test-codemode-geo.md +0 -177
- package/test-server/test-codemode/test-codemode-introspection.md +0 -190
- package/test-server/test-codemode/test-codemode-json.md +0 -237
- package/test-server/test-codemode/test-codemode-migration.md +0 -278
- package/test-server/test-codemode/test-codemode-sandbox.md +0 -413
- package/test-server/test-codemode/test-codemode-stats.md +0 -232
- package/test-server/test-codemode/test-codemode-text.md +0 -237
- package/test-server/test-codemode/test-codemode-transactions.md +0 -236
- package/test-server/test-codemode/test-codemode-vector.md +0 -244
- package/test-server/test-codemode/test-codemode-wasm-degradation.md +0 -394
- package/test-server/test-database.sql +0 -424
- package/test-server/test-preflight.md +0 -53
- package/test-server/test-prompts.md +0 -354
- package/test-server/test-resources.md +0 -272
- package/test-server/test-tool-groups/README.md +0 -100
- package/test-server/test-tool-groups/test-admin-core.md +0 -165
- package/test-server/test-tool-groups/test-admin-extensions.md +0 -133
- package/test-server/test-tool-groups/test-core-data.md +0 -262
- package/test-server/test-tool-groups/test-core-schema.md +0 -240
- package/test-server/test-tool-groups/test-geo-haversine.md +0 -130
- package/test-server/test-tool-groups/test-geo-spatialite.md +0 -110
- package/test-server/test-tool-groups/test-introspection-diagnostics.md +0 -123
- package/test-server/test-tool-groups/test-introspection-schema.md +0 -133
- package/test-server/test-tool-groups/test-json-read.md +0 -219
- package/test-server/test-tool-groups/test-json-write.md +0 -157
- package/test-server/test-tool-groups/test-migration.md +0 -193
- package/test-server/test-tool-groups/test-stats-advanced.md +0 -118
- package/test-server/test-tool-groups/test-stats-basic.md +0 -156
- package/test-server/test-tool-groups/test-text-advanced.md +0 -169
- package/test-server/test-tool-groups/test-text-basic.md +0 -177
- package/test-server/test-tool-groups/test-transactions.md +0 -179
- package/test-server/test-tool-groups/test-vector-read.md +0 -130
- package/test-server/test-tool-groups/test-vector-write.md +0 -115
- package/test-server/tool-reference.md +0 -257
- package/tsconfig.build.json +0 -6
- package/tsconfig.test.json +0 -9
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { TOOL_GROUPS, parseToolFilter, getToolFilterFromEnv, logger, getFilterSummary, DbMcpError } from './chunk-645ZEFLA.js';
|
|
1
|
+
import { VERSION, NAME, READ_ONLY, SERVER_ICONS, ASSISTANT_FOCUSED, redactObject, getRequiredScope, AuditListBackupsOutputSchema, AuditListBackupsSchema, AuditGetBackupOutputSchema, AuditCleanupOutputSchema, AuditDiffBackupOutputSchema, AuditRestoreBackupOutputSchema } from './chunk-E5IESRTK.js';
|
|
2
|
+
import { parseToolFilter, getToolFilterFromEnv, logger, getFilterSummary, DbMcpError, getAuthContext, scopesGrantToolAccess, registerToolScopes, InsufficientScopeError, sanitizeErrorMessage, formatHandlerError } from './chunk-L552U3QS.js';
|
|
4
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
4
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
6
5
|
import { open, stat, mkdir, rename, readdir, unlink, mkdtemp, writeFile, rmdir, readFile, appendFile } from 'fs/promises';
|
|
@@ -24,17 +23,17 @@ var INSTRUCTIONS = `# db-mcp (SQLite MCP Server)
|
|
|
24
23
|
|
|
25
24
|
## Built-in Tools
|
|
26
25
|
|
|
27
|
-
\`server_info\`, \`server_health\`, \`list_adapters\` \u2014
|
|
26
|
+
\`server_info\`, \`server_health\`, \`list_adapters\`, \`sqlite_execute_code\` \u2014 injected into all configurations.
|
|
28
27
|
|
|
29
28
|
## Help Resources
|
|
30
29
|
|
|
31
30
|
Read \`sqlite://help\` for gotchas and critical usage patterns.
|
|
32
|
-
Read \`sqlite://help/{group}\` for group-specific tool reference (json, text, stats, vector, geo, admin, transactions, introspection, migration).
|
|
31
|
+
Read \`sqlite://help/{group}\` for group-specific tool reference (core, json, text, stats, vector, geo, admin, transactions, introspection, migration).
|
|
33
32
|
Only help resources for your enabled tool groups are registered.`;
|
|
34
33
|
var HELP_CONTENT = /* @__PURE__ */ new Map([
|
|
35
34
|
[
|
|
36
35
|
"admin",
|
|
37
|
-
`# db-mcp Help \u2014 Database Administration (
|
|
36
|
+
`# db-mcp Help \u2014 Database Administration (32N/31W tools) + Server Audit (5 tools)
|
|
38
37
|
|
|
39
38
|
## Maintenance
|
|
40
39
|
|
|
@@ -44,21 +43,28 @@ sqlite_optimize({ analyze: true, reindex: true }); // optimize performance
|
|
|
44
43
|
sqlite_vacuum(); // reclaim space
|
|
45
44
|
sqlite_analyze({ table: "orders" }); // update statistics for query planner
|
|
46
45
|
sqlite_dbstat({ summarize: true }); // storage stats (\u26A0\uFE0F summarize native-only; WASM returns counts only)
|
|
46
|
+
sqlite_reindex(); // rebuild all indexes
|
|
47
|
+
sqlite_reindex({ target: "idx_users_email" }); // rebuild specific index
|
|
48
|
+
sqlite_reindex({ target: "orders" }); // rebuild all indexes for a table
|
|
47
49
|
\`\`\`
|
|
48
50
|
|
|
49
51
|
## Backup/Restore (Native only)
|
|
50
52
|
|
|
51
53
|
\`\`\`javascript
|
|
52
54
|
sqlite_backup({ targetPath: "/path/to/backup.db" });
|
|
55
|
+
sqlite_vacuum_into({ outputPath: "/path/to/compact.db" }); // create defragmented copy
|
|
56
|
+
sqlite_dump({ outputPath: "/path/to/dump.sql" }); // export SQL text dump
|
|
53
57
|
sqlite_verify_backup({ backupPath: "/path/to/backup.db" }); // check integrity without restoring
|
|
54
58
|
sqlite_restore({ sourcePath: "/path/to/backup.db" }); // \u26A0\uFE0F WARNING: Replaces current database
|
|
55
59
|
\`\`\`
|
|
56
60
|
|
|
57
|
-
## Audit Backups
|
|
61
|
+
## Audit Backups
|
|
58
62
|
|
|
59
63
|
\`\`\`javascript
|
|
60
|
-
sqlite_audit_list_backups(); // list pre-mutation DDL snapshots
|
|
64
|
+
sqlite_audit_list_backups({ limit: 10, offset: 0 }); // list pre-mutation DDL snapshots
|
|
61
65
|
sqlite_audit_get_backup({ filename: "snapshot_123.json" }); // retrieve specific snapshot
|
|
66
|
+
sqlite_audit_diff_backup({ filename: "snapshot_123.json" }); // compare snapshot against live schema
|
|
67
|
+
sqlite_audit_restore_backup({ filename: "snapshot_123.json", dryRun: true }); // restore schema from snapshot
|
|
62
68
|
sqlite_audit_cleanup(); // apply retention policy and delete old snapshots
|
|
63
69
|
\`\`\`
|
|
64
70
|
|
|
@@ -70,9 +76,21 @@ sqlite_pragma_settings({ pragma: "cache_size", value: 10000 }); // set value
|
|
|
70
76
|
sqlite_pragma_table_info({ table: "users" }); // column details
|
|
71
77
|
sqlite_pragma_compile_options({ filter: "FTS" }); // \u26A0\uFE0F WASM may show FTS3, not FTS5
|
|
72
78
|
sqlite_pragma_database_list(); // list attached databases
|
|
79
|
+
sqlite_attach_database({ filepath: "/path/to/other.db", alias: "archive" }); // attach external DB
|
|
80
|
+
sqlite_detach_database({ alias: "archive" }); // detach DB
|
|
73
81
|
sqlite_pragma_optimize(); // run PRAGMA optimize
|
|
74
82
|
\`\`\`
|
|
75
83
|
|
|
84
|
+
## WAL Management
|
|
85
|
+
|
|
86
|
+
\`\`\`javascript
|
|
87
|
+
sqlite_wal({ action: "status" }); // check current journal mode
|
|
88
|
+
sqlite_wal({ action: "enable" }); // switch to WAL mode
|
|
89
|
+
sqlite_wal({ action: "disable" }); // switch back to DELETE journal mode
|
|
90
|
+
sqlite_wal({ action: "checkpoint" }); // run default checkpoint
|
|
91
|
+
sqlite_wal({ action: "checkpoint", checkpointMode: "TRUNCATE" }); // checkpoint and truncate WAL file
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
76
94
|
## Index & Stats
|
|
77
95
|
|
|
78
96
|
- \`sqlite_index_stats({ table: "orders" })\` \u2014 stats for explicit indexes
|
|
@@ -132,19 +150,24 @@ sqlite_append_insight({ insight: "Q4 revenue increased 23% YoY" }); // add to me
|
|
|
132
150
|
],
|
|
133
151
|
[
|
|
134
152
|
"core",
|
|
135
|
-
`# db-mcp Help \u2014 Core Operations (
|
|
153
|
+
`# db-mcp Help \u2014 Core Operations (21 tools)
|
|
136
154
|
|
|
137
155
|
## Basic Queries
|
|
138
156
|
|
|
139
157
|
- \`sqlite_read_query({ query: "SELECT * FROM users LIMIT 10" })\` \u2014 execute SELECT, PRAGMA, EXPLAIN, or WITH statements
|
|
140
|
-
- \`sqlite_write_query({ query: "INSERT INTO users (name) VALUES ('Alice')" })\` \u2014 execute INSERT, UPDATE, DELETE, or DDL
|
|
158
|
+
- \`sqlite_write_query({ query: "INSERT INTO users (name) VALUES ('Alice')" })\` \u2014 execute INSERT, UPDATE, DELETE, REPLACE, or trigger DDL (CREATE/DROP TRIGGER)
|
|
141
159
|
|
|
142
160
|
## Tables & Schema
|
|
143
161
|
|
|
144
162
|
- \`sqlite_list_tables({ excludeSystemTables?: boolean })\` \u2014 list all tables in the database (system tables excluded by default)
|
|
145
|
-
- \`sqlite_describe_table({ table: "users" })\` \u2014 get detailed schema, columns, and foreign keys for a specific table
|
|
146
|
-
- \`sqlite_create_table({ table: "users", columns: [{ name: "id", type: "INTEGER PRIMARY KEY" }, { name: "email", type: "TEXT UNIQUE" }] })\` \u2014 create a new table
|
|
163
|
+
- \`sqlite_describe_table({ table: "users" })\` \u2014 get detailed schema, columns, and foreign keys for a specific table. Detects generated columns (VIRTUAL/STORED) with expression.
|
|
164
|
+
- \`sqlite_create_table({ table: "users", columns: [{ name: "id", type: "INTEGER PRIMARY KEY" }, { name: "email", type: "TEXT UNIQUE" }], foreignKeys: [{ column: "role_id", targetTable: "roles" }], checkConstraints: ["price > 0"] })\` \u2014 create a new table with optional table-level constraints. Use \`strict: true\` for STRICT mode (SQLite 3.37+) to enforce column type checking.
|
|
147
165
|
- \`sqlite_drop_table({ table: "users", ifExists?: true })\` \u2014 drop an existing table
|
|
166
|
+
- \`sqlite_alter_table({ table: "users", operation: "add_column", column: "age", type: "INTEGER", nullable: true })\` \u2014 add, rename, or drop columns, or rename a table. Operations: \`add_column\`, \`rename_column\`, \`drop_column\`, \`rename_table\`.
|
|
167
|
+
- \`sqlite_list_triggers({ table?: "users" })\` \u2014 list database triggers, optionally filtered by table
|
|
168
|
+
- \`sqlite_create_trigger({ name: "trg_updated", table: "users", timing: "AFTER", event: "UPDATE", body: "UPDATE users SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id" })\` \u2014 create a trigger with BEFORE/AFTER/INSTEAD OF timing, optional column-specific UPDATE triggers and WHEN conditions
|
|
169
|
+
- \`sqlite_drop_trigger({ name: "trg_updated" })\` \u2014 drop a database trigger
|
|
170
|
+
- \`sqlite_list_constraints({ table: "users" })\` \u2014 list primary key, foreign key, unique, and check constraints for a table
|
|
148
171
|
|
|
149
172
|
## Indexes
|
|
150
173
|
|
|
@@ -154,15 +177,17 @@ sqlite_append_insight({ insight: "Q4 revenue increased 23% YoY" }); // add to me
|
|
|
154
177
|
|
|
155
178
|
## Convenience Tools (High-Level Data Operations)
|
|
156
179
|
|
|
157
|
-
- \`sqlite_upsert({ table: "users", data:
|
|
158
|
-
- \`sqlite_batch_insert({ table: "users",
|
|
159
|
-
- \`sqlite_count({ table: "users",
|
|
160
|
-
- \`sqlite_exists({ table: "users",
|
|
161
|
-
- \`sqlite_truncate({ table: "users" })\` \u2014 quickly delete all rows from a table (executes \`DELETE FROM table\`)
|
|
180
|
+
- \`sqlite_upsert({ table: "users", data: { id: 1, name: "Alice" }, conflictColumns: ["id"], updateColumns: ["name"], returning: true })\` \u2014 insert or update a row using \`ON CONFLICT\` (or \`REPLACE\` fallback). Supports \`returning: true\` or array of columns.
|
|
181
|
+
- \`sqlite_batch_insert({ table: "users", rows: [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }], returning: true })\` \u2014 insert multiple rows in a single batch. Supports \`returning: true\` or array of columns.
|
|
182
|
+
- \`sqlite_count({ table: "users", where?: "status = 'active'" })\` \u2014 count rows in a table (faster than a full query)
|
|
183
|
+
- \`sqlite_exists({ table: "users", where: "email = 'test@example.com'" })\` \u2014 check if a row exists (stops at first match)
|
|
184
|
+
- \`sqlite_truncate({ table: "users" })\` \u2014 quickly delete all rows from a table (executes \`DELETE FROM table\`)
|
|
185
|
+
- \`sqlite_date_add({ table: "users", column: "created_at", amount: 7, unit: "days", whereClause: "id = 1" })\` \u2014 add or subtract time intervals from a date column. By default returns only the computed column; use \`selectColumns\` to return additional context.
|
|
186
|
+
- \`sqlite_date_diff({ table: "users", column1: "ended_at", column2: "started_at", unit: "days", whereClause: "id = 1" })\` \u2014 calculate the difference between two date columns. By default returns only the computed column; use \`selectColumns\` to return additional context.`
|
|
162
187
|
],
|
|
163
188
|
[
|
|
164
189
|
"geo",
|
|
165
|
-
`# db-mcp Help \u2014 Geospatial Operations (4 basic + 7 SpatiaLite)
|
|
190
|
+
`# db-mcp Help \u2014 Geospatial Operations (11N/4W: 4 basic + 7 SpatiaLite [NATIVE ONLY])
|
|
166
191
|
|
|
167
192
|
## Basic Geo (always available \u2014 Haversine formula)
|
|
168
193
|
|
|
@@ -275,7 +300,7 @@ sqlite_spatialite_index({
|
|
|
275
300
|
|
|
276
301
|
## \u26A0\uFE0F Critical Gotchas
|
|
277
302
|
|
|
278
|
-
1. **sqlite_write_query**:
|
|
303
|
+
1. **sqlite_write_query**: DML only (INSERT/UPDATE/DELETE/REPLACE) \u2014 use \`sqlite_read_query\` for SELECT, and dedicated DDL tools like \`sqlite_create_table\`, \`sqlite_create_trigger\`, and \`sqlite_drop_trigger\` for schema modifications.
|
|
279
304
|
2. **Regex patterns**: Double-escape backslashes (\`\\\\\\\\\`) when passing through JSON/MCP
|
|
280
305
|
3. **FTS5 virtual tables**: \`*_fts\` and shadow tables \`*_fts_*\` are hidden from \`sqlite_list_tables\` for cleaner output
|
|
281
306
|
4. **FTS5 boolean logic**: Uses AND by default \u2014 \`"machine learning"\` = rows with BOTH words. Use OR explicitly: \`"machine OR learning"\`
|
|
@@ -286,13 +311,16 @@ sqlite_spatialite_index({
|
|
|
286
311
|
9. **Fuzzy matching tokenization**: Matches WORD TOKENS by default \u2014 \`"laptop"\` matches \`"Laptop Pro 15"\` (distance 0 on first token). Use \`tokenize: false\` for full-string matching
|
|
287
312
|
10. **SpatiaLite distances**: \`nearest_neighbor\`/\`distance_matrix\` return CARTESIAN distance (degrees), not geodetic (km/miles)
|
|
288
313
|
11. **SpatiaLite buffer**: Auto-simplifies output by default (tolerance=0.0001). Use \`simplifyTolerance: 0\` to disable
|
|
289
|
-
12. **sqlite_stats_top_n**:
|
|
314
|
+
12. **sqlite_stats_top_n**: Returns all columns by default which creates large payloads for wide tables \u2014 always pass \`selectColumns\` to control output size
|
|
290
315
|
13. **CSV virtual tables**: Require ABSOLUTE file paths
|
|
291
316
|
14. **sqlite_create_series_table**: Creates a REGULAR table (not virtual) \u2014 use \`sqlite_drop_table\` to remove
|
|
292
317
|
15. **sqlite_dbstat**: \`summarize\` only works in native; WASM returns counts only
|
|
293
318
|
16. **PRAGMA compile options**: WASM may show FTS3, not FTS5
|
|
294
319
|
17. **Vector tool schemas**: Vector tools use distinct schemas for specific operations. E.g., \`sqlite.vector.dimensions\` requires \`vectorColumn\`. Additionally, \`sqlite.vector.get\` wraps metadata inside a \`metadata\` object (e.g., \`metadata.content\`), and \`sqlite.vector.stats\` returns \`sampleSize\` and \`magnitudeStats\` (not \`count\` and \`stats\`).
|
|
295
320
|
18. **FTS5 trigger cleanup**: Dropping an FTS5 table with \`sqlite_drop_table\` automatically finds and removes the associated \`_ai\`, \`_ad\`, and \`_au\` sync triggers from the source table.
|
|
321
|
+
19. **sqlite_batch_insert**: All rows must have the same keys \u2014 inconsistent column sets across rows will cause errors or unexpected NULLs
|
|
322
|
+
20. **sqlite_schema_diff**: \`baseline\` and \`target\` accept either the string \`"current"\` (queries live DB) or an inline snapshot object from a prior \`sqlite_schema_snapshot\` call. At least one side must be \`"current"\` unless doing an offline comparison
|
|
323
|
+
21. **sqlite_upsert**: Always specify \`conflictColumns\` \u2014 without it, falls back to \`REPLACE\` which deletes and re-inserts the row, potentially losing columns not included in \`data\`
|
|
296
324
|
|
|
297
325
|
## WASM vs Native
|
|
298
326
|
|
|
@@ -302,14 +330,14 @@ sqlite_spatialite_index({
|
|
|
302
330
|
| Transactions (8 tools) | \u2705 | \u274C | None |
|
|
303
331
|
| Window functions (6 tools in stats group) | \u2705 | \u274C | None |
|
|
304
332
|
| SpatiaLite GIS (7 tools; 4 basic geo always work) | \u2705 | \u274C | None |
|
|
305
|
-
| Backup/Restore (
|
|
333
|
+
| Backup/Restore/Dump/VacuumInto/Verify (5 tools) | \u2705 | \u274C | Graceful error |
|
|
306
334
|
| R-Tree spatial indexing | \u2705 | \u274C | Graceful error |
|
|
307
335
|
| CSV virtual tables | \u2705 | \u274C | Graceful error |
|
|
308
336
|
| generate_series | JS fallback | JS fallback | \u2014 |
|
|
309
337
|
| dbstat | \u2705 native (per-table) | \u274C | JS (counts only) |
|
|
310
338
|
| soundex() | \u2705 native | \u274C | JS |
|
|
311
339
|
|
|
312
|
-
## Code Mode (
|
|
340
|
+
## Code Mode (Built-in)
|
|
313
341
|
|
|
314
342
|
| Tool | Description |
|
|
315
343
|
| --------------------- | ----------------------------------------------------------------- |
|
|
@@ -317,6 +345,7 @@ sqlite_spatialite_index({
|
|
|
317
345
|
|
|
318
346
|
**Usage**: \`sqlite_execute_code({ code: "const tables = await sqlite.core.listTables(); return tables;" })\`
|
|
319
347
|
**Discover**: \`sqlite.help()\` for all groups, \`sqlite.<group>.help()\` for methods.
|
|
348
|
+
**Progress**: Use \`await sqlite.reportProgress(current, total, "Message")\` for custom long-running tasks.
|
|
320
349
|
**Groups**: \`sqlite.core\`, \`sqlite.json\`, \`sqlite.text\`, \`sqlite.stats\`, \`sqlite.vector\`, \`sqlite.admin\`, \`sqlite.transactions\` (Native-only), \`sqlite.geo\`, \`sqlite.introspection\`, \`sqlite.migration\`
|
|
321
350
|
|
|
322
351
|
> **Note**: Code Mode dynamically filters capabilities. In WASM environments, \`sqlite.help()\` will omit unsupported groups (e.g., \`transactions\`) and tools (e.g., FTS5) to accurately reflect the active runtime.
|
|
@@ -324,6 +353,7 @@ sqlite_spatialite_index({
|
|
|
324
353
|
## Code Mode API Mapping
|
|
325
354
|
|
|
326
355
|
\`sqlite_group_action\` \u2192 \`sqlite.group.action()\` (group prefixes dropped: \`sqlite_json_insert\` \u2192 \`sqlite.json.insert()\`)
|
|
356
|
+
**Exception**: \`stats\` and \`migration\` keep their prefix: \`sqlite_stats_basic\` \u2192 \`sqlite.stats.statsBasic()\`, \`sqlite_migration_apply\` \u2192 \`sqlite.migration.migrationApply()\`
|
|
327
357
|
|
|
328
358
|
**Positional args work**: \`sqlite.core.readQuery("SELECT...")\`, \`sqlite.json.insert("docs", "data", {...})\`
|
|
329
359
|
|
|
@@ -331,7 +361,7 @@ sqlite_spatialite_index({
|
|
|
331
361
|
],
|
|
332
362
|
[
|
|
333
363
|
"introspection",
|
|
334
|
-
`# db-mcp Help \u2014 Schema Introspection (
|
|
364
|
+
`# db-mcp Help \u2014 Schema Introspection (10 tools)
|
|
335
365
|
|
|
336
366
|
All introspection tools are **read-only** \u2014 they query PRAGMAs and sqlite_master, never modify data.
|
|
337
367
|
|
|
@@ -347,11 +377,11 @@ sqlite_topological_sort({ direction: "create", excludeSystemTables: true });
|
|
|
347
377
|
sqlite_topological_sort({ direction: "drop" }); // safe DROP order
|
|
348
378
|
|
|
349
379
|
// Simulate DELETE/DROP/TRUNCATE impact \u2014 shows affected tables, cascade paths, severity scoring
|
|
350
|
-
sqlite_cascade_simulator({ table: "users", operation: "
|
|
351
|
-
sqlite_cascade_simulator({ table: "users", operation: "
|
|
380
|
+
sqlite_cascade_simulator({ table: "users", operation: "DELETE" });
|
|
381
|
+
sqlite_cascade_simulator({ table: "users", operation: "DROP", compact: true }); // compact omits path arrays
|
|
352
382
|
\`\`\`
|
|
353
383
|
|
|
354
|
-
## Schema Analysis (
|
|
384
|
+
## Schema Analysis (4 tools)
|
|
355
385
|
|
|
356
386
|
\`\`\`javascript
|
|
357
387
|
// Full schema in one call \u2014 compact: true omits column details, sections limits scope
|
|
@@ -361,6 +391,20 @@ sqlite_schema_snapshot({
|
|
|
361
391
|
});
|
|
362
392
|
sqlite_schema_snapshot({ compact: true }); // lighter payload
|
|
363
393
|
|
|
394
|
+
// Compare a saved snapshot against the current live schema \u2014 structured drift analysis
|
|
395
|
+
sqlite_schema_diff({
|
|
396
|
+
baseline: previousSnapshot, // from an earlier sqlite_schema_snapshot call
|
|
397
|
+
target: "current",
|
|
398
|
+
});
|
|
399
|
+
// Compare specific sections only
|
|
400
|
+
sqlite_schema_diff({
|
|
401
|
+
baseline: "current",
|
|
402
|
+
target: modifiedSnapshot,
|
|
403
|
+
sections: ["tables", "indexes"],
|
|
404
|
+
});
|
|
405
|
+
// Both sides inline (offline diff, no DB queries)
|
|
406
|
+
sqlite_schema_diff({ baseline: snapshotA, target: snapshotB });
|
|
407
|
+
|
|
364
408
|
// Find constraint health issues \u2014 missing PKs, nullable FKs, unindexed FKs
|
|
365
409
|
sqlite_constraint_analysis({ excludeSystemTables: true });
|
|
366
410
|
sqlite_constraint_analysis({
|
|
@@ -402,13 +446,13 @@ sqlite_query_plan({ sql: "SELECT * FROM orders WHERE status = 'active'" });
|
|
|
402
446
|
],
|
|
403
447
|
[
|
|
404
448
|
"json",
|
|
405
|
-
`# db-mcp Help \u2014 JSON Operations (
|
|
449
|
+
`# db-mcp Help \u2014 JSON Operations (25 tools)
|
|
406
450
|
|
|
407
451
|
## Collection & CRUD
|
|
408
452
|
|
|
409
453
|
- \`sqlite_create_json_collection({ tableName, indexes: [{ path: "$.type" }, { path: "$.author" }] })\` \u2014 creates table with JSON indexes
|
|
410
454
|
- \`sqlite_json_insert({ table, column, data: { type: "article", title: "Hello", tags: ["news"] } })\` \u2014 insert JSON document
|
|
411
|
-
- \`sqlite_json_select({ table, column,
|
|
455
|
+
- \`sqlite_json_select({ table, column, paths? })\` \u2014 select rows, optionally extract specific JSON paths
|
|
412
456
|
- \`sqlite_json_update({ table, column, path, value, whereClause })\` \u2014 update value at JSON path
|
|
413
457
|
- \`sqlite_json_query({ table, column, filterPaths: { "$.type": "article" }, selectPaths: ["$.title"] })\` \u2014 query with path-based filters and projections
|
|
414
458
|
|
|
@@ -463,9 +507,10 @@ sqlite_json_group_object({
|
|
|
463
507
|
\`\`\`
|
|
464
508
|
|
|
465
509
|
- \`sqlite_json_keys({ table, column, path? })\` \u2014 get distinct keys of JSON objects
|
|
466
|
-
- \`sqlite_json_pretty({
|
|
467
|
-
- \`sqlite_json_valid({
|
|
510
|
+
- \`sqlite_json_pretty({ json: "{\\"name\\": \\"Alice\\"}" })\` \u2014 format JSON string with indentation for readability
|
|
511
|
+
- \`sqlite_json_valid({ json: "{\\"name\\": \\"Alice\\"}" })\` \u2014 check if a string is valid JSON
|
|
468
512
|
- \`sqlite_json_analyze_schema({ table, column })\` \u2014 infer schema types
|
|
513
|
+
- \`sqlite_json_diff({ table, column, path1, path2 })\` \u2014 compare two JSON paths within the same row
|
|
469
514
|
|
|
470
515
|
## Security
|
|
471
516
|
|
|
@@ -492,8 +537,7 @@ sqlite_migration_init();
|
|
|
492
537
|
sqlite_migration_apply({
|
|
493
538
|
version: "2024-01-15-add-users",
|
|
494
539
|
description: "Create users table",
|
|
495
|
-
sql:
|
|
496
|
-
"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE)",
|
|
540
|
+
sql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE)",
|
|
497
541
|
rollbackSql: "DROP TABLE users",
|
|
498
542
|
sourceSystem: "agent",
|
|
499
543
|
appliedBy: "claude",
|
|
@@ -522,11 +566,11 @@ sqlite_migration_status();
|
|
|
522
566
|
## \u26A0\uFE0F Gotchas
|
|
523
567
|
|
|
524
568
|
- Rollback requires \`rollbackSql\` to have been provided when the migration was recorded/applied
|
|
525
|
-
- Migration group is **opt-in** \u2014 not included
|
|
569
|
+
- Migration group is **opt-in** \u2014 not included by default. Enable via \`--tool-filter\` flag: use \`dev-schema\` (core+introspection+migration+codemode) or \`full\` (all groups)`
|
|
526
570
|
],
|
|
527
571
|
[
|
|
528
572
|
"stats",
|
|
529
|
-
`# db-mcp Help \u2014 Statistical Analysis (
|
|
573
|
+
`# db-mcp Help \u2014 Statistical Analysis (23N/17W: 17 core + 6 window [NATIVE ONLY])
|
|
530
574
|
|
|
531
575
|
## Core Statistics (always available)
|
|
532
576
|
|
|
@@ -542,6 +586,7 @@ sqlite_stats_percentile({
|
|
|
542
586
|
sqlite_stats_histogram({ table: "products", column: "price", buckets: 10 });
|
|
543
587
|
sqlite_stats_correlation({ table: "data", column1: "x", column2: "y" }); // Pearson coefficient
|
|
544
588
|
sqlite_stats_distinct({ table: "orders", column: "status" }); // distinct values
|
|
589
|
+
sqlite_stats_sample({ table: "orders", sampleSize: 100 }); // random sample
|
|
545
590
|
sqlite_stats_summary({
|
|
546
591
|
table: "data",
|
|
547
592
|
columns: ["price", "quantity", "discount"],
|
|
@@ -642,13 +687,13 @@ sqlite_window_moving_avg({
|
|
|
642
687
|
column: "close_price",
|
|
643
688
|
orderBy: "date",
|
|
644
689
|
windowSize: 7,
|
|
645
|
-
selectColumns: ["date"]
|
|
690
|
+
selectColumns: ["date"],
|
|
646
691
|
});
|
|
647
692
|
\`\`\``
|
|
648
693
|
],
|
|
649
694
|
[
|
|
650
695
|
"text",
|
|
651
|
-
`# db-mcp Help \u2014 Text Processing & FTS5
|
|
696
|
+
`# db-mcp Help \u2014 Text Processing & FTS5 (19N/14W: 14 text + 5 FTS5 [NATIVE ONLY])
|
|
652
697
|
|
|
653
698
|
## Full-Text Search / FTS5 (5 tools, Native only)
|
|
654
699
|
|
|
@@ -775,11 +820,16 @@ sqlite_advanced_search({
|
|
|
775
820
|
fuzzyThreshold: 0.4,
|
|
776
821
|
});
|
|
777
822
|
|
|
778
|
-
// Sentiment analysis \u2014
|
|
823
|
+
// Sentiment analysis \u2014 text analysis (can analyze raw text or database columns)
|
|
779
824
|
sqlite_text_sentiment({ text: "This product is amazing and wonderful!" });
|
|
780
825
|
// \u2192 { sentiment: "very_positive", score: 2, confidence: "medium" }
|
|
781
826
|
|
|
782
|
-
sqlite_text_sentiment({
|
|
827
|
+
sqlite_text_sentiment({ table: "articles", column: "body" }); // analyzes all rows in a column
|
|
828
|
+
|
|
829
|
+
sqlite_text_sentiment({
|
|
830
|
+
text: "Great service but slow delivery",
|
|
831
|
+
returnWords: true,
|
|
832
|
+
});
|
|
783
833
|
// \u2192 { sentiment: "neutral", score: 0, matchedPositive: ["great"], matchedNegative: ["slow"] }
|
|
784
834
|
\`\`\``
|
|
785
835
|
],
|
|
@@ -883,11 +933,12 @@ var AuditLogger = class {
|
|
|
883
933
|
await this.ensureDirectory();
|
|
884
934
|
const fh = await open(this.config.logPath, "a");
|
|
885
935
|
await fh.close();
|
|
886
|
-
} catch {
|
|
936
|
+
} catch (err) {
|
|
887
937
|
process.stderr.write(
|
|
888
938
|
`[AUDIT] Failed to initialise log file: ${this.config.logPath}
|
|
889
939
|
`
|
|
890
940
|
);
|
|
941
|
+
throw err;
|
|
891
942
|
}
|
|
892
943
|
}
|
|
893
944
|
/**
|
|
@@ -897,7 +948,8 @@ var AuditLogger = class {
|
|
|
897
948
|
*/
|
|
898
949
|
log(entry) {
|
|
899
950
|
if (this.closed || !this.config.enabled) return;
|
|
900
|
-
|
|
951
|
+
const safeEntry = redactObject(entry, 0, 5);
|
|
952
|
+
this.buffer.push(JSON.stringify(safeEntry));
|
|
901
953
|
if (this.buffer.length >= BUFFER_HIGH_WATER) {
|
|
902
954
|
void this.flush();
|
|
903
955
|
}
|
|
@@ -1033,9 +1085,9 @@ var gzipAsync = promisify(gzip);
|
|
|
1033
1085
|
var SNAPSHOT_TOOL_ARGS = {
|
|
1034
1086
|
sqlite_drop_table: { targetKey: "table" },
|
|
1035
1087
|
sqlite_drop_index: { targetKey: "index" },
|
|
1036
|
-
sqlite_drop_view: { targetKey: "
|
|
1088
|
+
sqlite_drop_view: { targetKey: "viewName" },
|
|
1037
1089
|
sqlite_import_csv: { targetKey: "table" },
|
|
1038
|
-
sqlite_backup: { targetKey: "
|
|
1090
|
+
sqlite_backup: { targetKey: "targetPath" }
|
|
1039
1091
|
};
|
|
1040
1092
|
var SNAPSHOT_EXT = ".snapshot.json.gz";
|
|
1041
1093
|
var SNAPSHOT_EXT_LEGACY = ".snapshot.json";
|
|
@@ -1087,14 +1139,18 @@ var BackupManager = class {
|
|
|
1087
1139
|
/**
|
|
1088
1140
|
* List available snapshots with metadata.
|
|
1089
1141
|
*/
|
|
1090
|
-
async listSnapshots() {
|
|
1142
|
+
async listSnapshots(limit = 10, offset = 0) {
|
|
1091
1143
|
try {
|
|
1092
1144
|
await this.ensureDirectory();
|
|
1093
1145
|
const files = await readdir(this.snapshotDir);
|
|
1146
|
+
const snapshotFiles = files.filter(
|
|
1147
|
+
(f) => f.endsWith(SNAPSHOT_EXT) || f.endsWith(SNAPSHOT_EXT_LEGACY)
|
|
1148
|
+
);
|
|
1149
|
+
snapshotFiles.sort((a, b) => b.localeCompare(a));
|
|
1150
|
+
const total = snapshotFiles.length;
|
|
1151
|
+
const targetFiles = snapshotFiles.slice(offset, offset + limit);
|
|
1094
1152
|
const snapshots = [];
|
|
1095
|
-
for (const file of
|
|
1096
|
-
if (!file.endsWith(SNAPSHOT_EXT) && !file.endsWith(SNAPSHOT_EXT_LEGACY))
|
|
1097
|
-
continue;
|
|
1153
|
+
for (const file of targetFiles) {
|
|
1098
1154
|
try {
|
|
1099
1155
|
const parsed = await this.readSnapshotFile(file);
|
|
1100
1156
|
if (parsed) {
|
|
@@ -1103,10 +1159,9 @@ var BackupManager = class {
|
|
|
1103
1159
|
} catch {
|
|
1104
1160
|
}
|
|
1105
1161
|
}
|
|
1106
|
-
snapshots
|
|
1107
|
-
return snapshots;
|
|
1162
|
+
return { snapshots, total };
|
|
1108
1163
|
} catch {
|
|
1109
|
-
return [];
|
|
1164
|
+
return { snapshots: [], total: 0 };
|
|
1110
1165
|
}
|
|
1111
1166
|
}
|
|
1112
1167
|
/**
|
|
@@ -1400,32 +1455,57 @@ var BackupManager = class {
|
|
|
1400
1455
|
}
|
|
1401
1456
|
}
|
|
1402
1457
|
};
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1458
|
+
var SENSITIVE_KEY_PATTERN = /^(password|passwd|token|secret|authorization|api_?key|credential|private_?key|access_?token|refresh_?token)$/i;
|
|
1459
|
+
var SENSITIVE_VALUE_PATTERN = /(?:sk-|Bearer |token\s*[:=]\s*|password\s*[:=]\s*|secret\s*[:=]\s*|apikey\s*[:=]\s*|api_key\s*[:=]\s*|AWS_SECRET_ACCESS_KEY\s*[:=]\s*|GITHUB_TOKEN\s*[:=]\s*|ghp_|gho_|ghu_|ghs_|xoxb-|xoxp-|xoxs-|AZURE_[A-Z_]*\s*[:=]\s*|DATABASE_URL\s*[:=]\s*|AKIA|sk-ant-api[a-zA-Z0-9_-]+|sk_live_[a-zA-Z0-9_]+|rk_live_[a-zA-Z0-9_]+|SG\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+|npm_[a-zA-Z0-9]{30,}|dpl_[a-zA-Z0-9]{30,}|hvs\.[a-zA-Z0-9_-]+)[^\s'",;)}\]]{4,}/gi;
|
|
1460
|
+
function redactSensitiveKeys(value, depth = 0) {
|
|
1461
|
+
const MAX_DEPTH = 5;
|
|
1462
|
+
if (depth > MAX_DEPTH || value === null || value === void 0) {
|
|
1463
|
+
return value;
|
|
1464
|
+
}
|
|
1465
|
+
if (Array.isArray(value)) {
|
|
1466
|
+
return value.map((item) => redactSensitiveKeys(item, depth + 1));
|
|
1467
|
+
}
|
|
1468
|
+
if (typeof value === "string") {
|
|
1469
|
+
const isSql = /^\s*(?:SELECT|INSERT|UPDATE|DELETE|WITH|CREATE|ALTER|DROP|PRAGMA)\b/i.test(
|
|
1470
|
+
value
|
|
1471
|
+
);
|
|
1472
|
+
const scrubbed = isSql ? value.replace(/'(?:''|[^'])*'/g, "'***'") : value;
|
|
1473
|
+
return scrubbed.replace(SENSITIVE_VALUE_PATTERN, "[REDACTED]");
|
|
1474
|
+
}
|
|
1475
|
+
if (typeof value === "object") {
|
|
1476
|
+
const result = {};
|
|
1477
|
+
for (const [key, val] of Object.entries(value)) {
|
|
1478
|
+
if (SENSITIVE_KEY_PATTERN.test(key)) {
|
|
1479
|
+
result[key] = "[REDACTED]";
|
|
1480
|
+
} else if (typeof val === "object" && val !== null) {
|
|
1481
|
+
result[key] = redactSensitiveKeys(val, depth + 1);
|
|
1482
|
+
} else if (typeof val === "string") {
|
|
1483
|
+
const isSql = key.toLowerCase() === "sql" || key.toLowerCase() === "query" || /^\s*(?:SELECT|INSERT|UPDATE|DELETE|WITH|CREATE|ALTER|DROP|PRAGMA)\b/i.test(
|
|
1484
|
+
val
|
|
1485
|
+
);
|
|
1486
|
+
const scrubbed = isSql ? val.replace(/'(?:''|[^'])*'/g, "'***'") : val;
|
|
1487
|
+
result[key] = scrubbed.replace(SENSITIVE_VALUE_PATTERN, "[REDACTED]");
|
|
1488
|
+
} else {
|
|
1489
|
+
result[key] = val;
|
|
1490
|
+
}
|
|
1412
1491
|
}
|
|
1492
|
+
return result;
|
|
1413
1493
|
}
|
|
1494
|
+
return value;
|
|
1414
1495
|
}
|
|
1415
|
-
function getRequiredScope(toolName) {
|
|
1416
|
-
return toolScopeMap.get(toolName) ?? SCOPES.READ;
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
// src/audit/interceptor.ts
|
|
1420
1496
|
var ALWAYS_AUDITED_SCOPES = /* @__PURE__ */ new Set(["write", "admin"]);
|
|
1421
1497
|
function scopeToCategory(scope) {
|
|
1422
1498
|
if (scope === "admin") return "admin";
|
|
1423
1499
|
if (scope === "read") return "read";
|
|
1424
1500
|
return "write";
|
|
1425
1501
|
}
|
|
1426
|
-
function createAuditInterceptor(auditLogger, backupManager
|
|
1502
|
+
function createAuditInterceptor(auditLogger, backupManager) {
|
|
1427
1503
|
const auditReads = auditLogger.config.auditReads;
|
|
1504
|
+
let currentQueryAdapter;
|
|
1428
1505
|
return {
|
|
1506
|
+
setQueryAdapter(adapter) {
|
|
1507
|
+
currentQueryAdapter = adapter;
|
|
1508
|
+
},
|
|
1429
1509
|
async around(toolName, args, requestId, fn, options) {
|
|
1430
1510
|
const scope = getRequiredScope(toolName);
|
|
1431
1511
|
if (!ALWAYS_AUDITED_SCOPES.has(scope) && !auditReads) {
|
|
@@ -1438,6 +1518,18 @@ function createAuditInterceptor(auditLogger, backupManager, queryAdapter) {
|
|
|
1438
1518
|
let error;
|
|
1439
1519
|
let backupRef;
|
|
1440
1520
|
let tokenEstimate;
|
|
1521
|
+
if (backupManager !== void 0 && currentQueryAdapter !== void 0 && backupManager.shouldSnapshot(toolName)) {
|
|
1522
|
+
try {
|
|
1523
|
+
backupRef = await backupManager.createSnapshot(
|
|
1524
|
+
toolName,
|
|
1525
|
+
args ?? {},
|
|
1526
|
+
requestId,
|
|
1527
|
+
currentQueryAdapter,
|
|
1528
|
+
options?.logAs
|
|
1529
|
+
);
|
|
1530
|
+
} catch {
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1441
1533
|
try {
|
|
1442
1534
|
const result = await fn();
|
|
1443
1535
|
if (typeof result === "object" && result !== null) {
|
|
@@ -1455,7 +1547,9 @@ function createAuditInterceptor(auditLogger, backupManager, queryAdapter) {
|
|
|
1455
1547
|
return result;
|
|
1456
1548
|
} catch (err) {
|
|
1457
1549
|
success = false;
|
|
1458
|
-
error =
|
|
1550
|
+
error = sanitizeErrorMessage(
|
|
1551
|
+
err instanceof Error ? err.message : String(err)
|
|
1552
|
+
);
|
|
1459
1553
|
const errorResult = {
|
|
1460
1554
|
success: false,
|
|
1461
1555
|
error,
|
|
@@ -1495,7 +1589,7 @@ function createAuditInterceptor(auditLogger, backupManager, queryAdapter) {
|
|
|
1495
1589
|
durationMs,
|
|
1496
1590
|
success,
|
|
1497
1591
|
error,
|
|
1498
|
-
args: auditLogger.config.redact ? void 0 : args,
|
|
1592
|
+
args: auditLogger.config.redact ? void 0 : redactSensitiveKeys(args),
|
|
1499
1593
|
backup: backupRef,
|
|
1500
1594
|
tokenEstimate
|
|
1501
1595
|
});
|
|
@@ -1504,6 +1598,803 @@ function createAuditInterceptor(auditLogger, backupManager, queryAdapter) {
|
|
|
1504
1598
|
}
|
|
1505
1599
|
};
|
|
1506
1600
|
}
|
|
1601
|
+
|
|
1602
|
+
// src/server/registration/built-in-tools.ts
|
|
1603
|
+
function registerBuiltInTools(server, adaptersMap, config, toolFilter) {
|
|
1604
|
+
const serverInfoOpts = {
|
|
1605
|
+
title: "Server Info",
|
|
1606
|
+
description: "Get information about the db-mcp server and registered adapters",
|
|
1607
|
+
icons: SERVER_ICONS,
|
|
1608
|
+
annotations: READ_ONLY
|
|
1609
|
+
};
|
|
1610
|
+
server.registerTool("server_info", serverInfoOpts, () => {
|
|
1611
|
+
const authCtx = getAuthContext();
|
|
1612
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "server_info")) {
|
|
1613
|
+
throw new InsufficientScopeError(["read"], authCtx.scopes);
|
|
1614
|
+
}
|
|
1615
|
+
const adapterInfo = [];
|
|
1616
|
+
for (const [id, adapter] of adaptersMap) {
|
|
1617
|
+
adapterInfo.push({
|
|
1618
|
+
id,
|
|
1619
|
+
...adapter.getInfo()
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1622
|
+
return {
|
|
1623
|
+
content: [
|
|
1624
|
+
{
|
|
1625
|
+
type: "text",
|
|
1626
|
+
text: JSON.stringify(
|
|
1627
|
+
{
|
|
1628
|
+
name: config.name,
|
|
1629
|
+
version: config.version,
|
|
1630
|
+
transport: config.transport,
|
|
1631
|
+
adapters: adapterInfo,
|
|
1632
|
+
toolFilter: {
|
|
1633
|
+
raw: toolFilter.raw,
|
|
1634
|
+
enabledGroups: [...toolFilter.enabledGroups]
|
|
1635
|
+
}
|
|
1636
|
+
},
|
|
1637
|
+
null,
|
|
1638
|
+
2
|
|
1639
|
+
)
|
|
1640
|
+
}
|
|
1641
|
+
]
|
|
1642
|
+
};
|
|
1643
|
+
});
|
|
1644
|
+
const healthOpts = {
|
|
1645
|
+
title: "Server Health",
|
|
1646
|
+
description: "Check health status of all database connections",
|
|
1647
|
+
icons: SERVER_ICONS,
|
|
1648
|
+
annotations: READ_ONLY
|
|
1649
|
+
};
|
|
1650
|
+
server.registerTool("server_health", healthOpts, async () => {
|
|
1651
|
+
const authCtx = getAuthContext();
|
|
1652
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "server_health")) {
|
|
1653
|
+
throw new InsufficientScopeError(["read"], authCtx.scopes);
|
|
1654
|
+
}
|
|
1655
|
+
const health = {
|
|
1656
|
+
server: "healthy",
|
|
1657
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1658
|
+
adapters: {}
|
|
1659
|
+
};
|
|
1660
|
+
for (const [id, adapter] of adaptersMap) {
|
|
1661
|
+
try {
|
|
1662
|
+
const adapterHealth = await adapter.getHealth();
|
|
1663
|
+
health["adapters"][id] = adapterHealth;
|
|
1664
|
+
} catch (error) {
|
|
1665
|
+
let errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
1666
|
+
errorMsg = errorMsg.replace(/(:[^:@/]+@)/g, ":***@");
|
|
1667
|
+
health["adapters"][id] = {
|
|
1668
|
+
connected: false,
|
|
1669
|
+
error: errorMsg
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
return {
|
|
1674
|
+
content: [
|
|
1675
|
+
{
|
|
1676
|
+
type: "text",
|
|
1677
|
+
text: JSON.stringify(health, null, 2)
|
|
1678
|
+
}
|
|
1679
|
+
]
|
|
1680
|
+
};
|
|
1681
|
+
});
|
|
1682
|
+
const listAdaptersOpts = {
|
|
1683
|
+
title: "List Adapters",
|
|
1684
|
+
description: "List all registered database adapters",
|
|
1685
|
+
icons: SERVER_ICONS,
|
|
1686
|
+
annotations: READ_ONLY
|
|
1687
|
+
};
|
|
1688
|
+
server.registerTool("list_adapters", listAdaptersOpts, () => {
|
|
1689
|
+
const authCtx = getAuthContext();
|
|
1690
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "list_adapters")) {
|
|
1691
|
+
throw new InsufficientScopeError(["read"], authCtx.scopes);
|
|
1692
|
+
}
|
|
1693
|
+
const adapters = [];
|
|
1694
|
+
for (const [, adapter] of adaptersMap) {
|
|
1695
|
+
adapters.push({
|
|
1696
|
+
id: `${adapter.type}:default`,
|
|
1697
|
+
type: adapter.type,
|
|
1698
|
+
name: adapter.name,
|
|
1699
|
+
version: adapter.version,
|
|
1700
|
+
connected: adapter.isConnected()
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
return {
|
|
1704
|
+
content: [
|
|
1705
|
+
{
|
|
1706
|
+
type: "text",
|
|
1707
|
+
text: JSON.stringify(adapters, null, 2)
|
|
1708
|
+
}
|
|
1709
|
+
]
|
|
1710
|
+
};
|
|
1711
|
+
});
|
|
1712
|
+
registerToolScopes(
|
|
1713
|
+
/* @__PURE__ */ new Map([
|
|
1714
|
+
["server_info", ["read"]],
|
|
1715
|
+
["server_health", ["read"]],
|
|
1716
|
+
["list_adapters", ["read"]]
|
|
1717
|
+
])
|
|
1718
|
+
);
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
// src/server/registration/help-resources.ts
|
|
1722
|
+
function registerHelpResources(server, toolFilter) {
|
|
1723
|
+
const gotchasContent = HELP_CONTENT.get("gotchas");
|
|
1724
|
+
if (gotchasContent) {
|
|
1725
|
+
server.registerResource(
|
|
1726
|
+
"sqlite_help",
|
|
1727
|
+
"sqlite://help",
|
|
1728
|
+
{
|
|
1729
|
+
description: "Critical gotchas, WASM vs Native comparison, and Code Mode API reference",
|
|
1730
|
+
mimeType: "text/markdown",
|
|
1731
|
+
annotations: ASSISTANT_FOCUSED
|
|
1732
|
+
},
|
|
1733
|
+
() => ({
|
|
1734
|
+
contents: [
|
|
1735
|
+
{
|
|
1736
|
+
uri: "sqlite://help",
|
|
1737
|
+
mimeType: "text/markdown",
|
|
1738
|
+
text: gotchasContent
|
|
1739
|
+
}
|
|
1740
|
+
]
|
|
1741
|
+
})
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
const groupHelpKeys = [
|
|
1745
|
+
{ group: "core", key: "core" },
|
|
1746
|
+
{ group: "json", key: "json" },
|
|
1747
|
+
{ group: "text", key: "text" },
|
|
1748
|
+
{ group: "stats", key: "stats" },
|
|
1749
|
+
{ group: "vector", key: "vector" },
|
|
1750
|
+
{ group: "geo", key: "geo" },
|
|
1751
|
+
{ group: "admin", key: "admin" },
|
|
1752
|
+
{ group: "transactions", key: "transactions" },
|
|
1753
|
+
{ group: "introspection", key: "introspection" },
|
|
1754
|
+
{ group: "migration", key: "migration" }
|
|
1755
|
+
];
|
|
1756
|
+
for (const { group, key } of groupHelpKeys) {
|
|
1757
|
+
const isCodemodeOnly = toolFilter.enabledGroups.size === 1 && toolFilter.enabledGroups.has("codemode");
|
|
1758
|
+
if (!toolFilter.enabledGroups.has(group) && !isCodemodeOnly) {
|
|
1759
|
+
continue;
|
|
1760
|
+
}
|
|
1761
|
+
const content = HELP_CONTENT.get(key);
|
|
1762
|
+
if (!content) continue;
|
|
1763
|
+
server.registerResource(
|
|
1764
|
+
`sqlite_help_${key}`,
|
|
1765
|
+
`sqlite://help/${key}`,
|
|
1766
|
+
{
|
|
1767
|
+
description: `Tool reference for the ${group} tool group`,
|
|
1768
|
+
mimeType: "text/markdown",
|
|
1769
|
+
annotations: ASSISTANT_FOCUSED
|
|
1770
|
+
},
|
|
1771
|
+
() => ({
|
|
1772
|
+
contents: [
|
|
1773
|
+
{
|
|
1774
|
+
uri: `sqlite://help/${key}`,
|
|
1775
|
+
mimeType: "text/markdown",
|
|
1776
|
+
text: content
|
|
1777
|
+
}
|
|
1778
|
+
]
|
|
1779
|
+
})
|
|
1780
|
+
);
|
|
1781
|
+
}
|
|
1782
|
+
const registeredHelp = ["sqlite://help"];
|
|
1783
|
+
for (const { group, key } of groupHelpKeys) {
|
|
1784
|
+
if (toolFilter.enabledGroups.has(group)) {
|
|
1785
|
+
registeredHelp.push(`sqlite://help/${key}`);
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
logger.info(`Help resources: ${registeredHelp.join(", ")}`, {
|
|
1789
|
+
module: "SERVER"
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
function redactSqlLiterals(text) {
|
|
1793
|
+
return text.replace(/'(?:''|[^'])*'/g, "'***'");
|
|
1794
|
+
}
|
|
1795
|
+
function validateDdl(sql) {
|
|
1796
|
+
const cleanSql = sql.replace(/\/\*[\s\S]*?\*\//g, "").replace(/--.*$/gm, "");
|
|
1797
|
+
const upperSql = cleanSql.toUpperCase();
|
|
1798
|
+
if (upperSql.includes("ATTACH ") || upperSql.includes("DETACH ") || upperSql.includes("PRAGMA ") || upperSql.includes("LOAD_EXTENSION(")) {
|
|
1799
|
+
throw new Error(
|
|
1800
|
+
`DDL validation failed: unauthorized command or function call`
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1803
|
+
if (upperSql.includes(" ON MAIN.") || upperSql.includes(" ON TEMP.")) {
|
|
1804
|
+
throw new Error(
|
|
1805
|
+
`DDL validation failed: trigger attempts to target a specific database`
|
|
1806
|
+
);
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
function registerAuditResource(server, auditLogger, backupManager) {
|
|
1810
|
+
if (!auditLogger) return;
|
|
1811
|
+
server.registerResource(
|
|
1812
|
+
"sqlite_audit",
|
|
1813
|
+
"sqlite://audit",
|
|
1814
|
+
{
|
|
1815
|
+
description: "Recent audit log entries and backup statistics. Shows the last 50 tool invocations with timing, outcomes, and token estimates.",
|
|
1816
|
+
mimeType: "application/json"
|
|
1817
|
+
},
|
|
1818
|
+
async () => {
|
|
1819
|
+
const recent = await auditLogger.recent(50);
|
|
1820
|
+
const backupStats = backupManager ? await backupManager.getStats() : void 0;
|
|
1821
|
+
const payload = {
|
|
1822
|
+
entries: recent,
|
|
1823
|
+
stats: {
|
|
1824
|
+
totalEntries: recent.length,
|
|
1825
|
+
...backupStats && { backups: backupStats }
|
|
1826
|
+
}
|
|
1827
|
+
};
|
|
1828
|
+
const payloadStr = JSON.stringify(payload, null, 2);
|
|
1829
|
+
return {
|
|
1830
|
+
contents: [
|
|
1831
|
+
{
|
|
1832
|
+
uri: "sqlite://audit",
|
|
1833
|
+
mimeType: "application/json",
|
|
1834
|
+
text: redactSqlLiterals(payloadStr)
|
|
1835
|
+
}
|
|
1836
|
+
]
|
|
1837
|
+
};
|
|
1838
|
+
}
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
function registerAuditBackupTools(server, backupManager, adaptersMap) {
|
|
1842
|
+
if (!backupManager) return;
|
|
1843
|
+
server.registerTool(
|
|
1844
|
+
"sqlite_audit_list_backups",
|
|
1845
|
+
{
|
|
1846
|
+
title: "List Audit Backups",
|
|
1847
|
+
description: "List pre-mutation DDL snapshots captured before destructive operations. Returns metadata for each snapshot including timestamp, tool, target, and size.",
|
|
1848
|
+
inputSchema: AuditListBackupsSchema,
|
|
1849
|
+
outputSchema: AuditListBackupsOutputSchema,
|
|
1850
|
+
annotations: {
|
|
1851
|
+
readOnlyHint: true,
|
|
1852
|
+
destructiveHint: false,
|
|
1853
|
+
idempotentHint: true,
|
|
1854
|
+
openWorldHint: false
|
|
1855
|
+
}
|
|
1856
|
+
},
|
|
1857
|
+
async (args) => {
|
|
1858
|
+
const authCtx = getAuthContext();
|
|
1859
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "sqlite_audit_list_backups")) {
|
|
1860
|
+
throw new InsufficientScopeError(["admin", "full"], authCtx.scopes);
|
|
1861
|
+
}
|
|
1862
|
+
let parsed;
|
|
1863
|
+
try {
|
|
1864
|
+
parsed = AuditListBackupsSchema.parse(args ?? {});
|
|
1865
|
+
} catch (error) {
|
|
1866
|
+
const structured = formatHandlerError(error);
|
|
1867
|
+
return {
|
|
1868
|
+
content: [
|
|
1869
|
+
{
|
|
1870
|
+
type: "text",
|
|
1871
|
+
text: JSON.stringify(structured, null, 2)
|
|
1872
|
+
}
|
|
1873
|
+
],
|
|
1874
|
+
isError: true,
|
|
1875
|
+
structuredContent: structured
|
|
1876
|
+
};
|
|
1877
|
+
}
|
|
1878
|
+
const limit = parsed.limit ?? 10;
|
|
1879
|
+
const offset = parsed.offset ?? 0;
|
|
1880
|
+
const { snapshots, total } = await backupManager.listSnapshots(
|
|
1881
|
+
limit,
|
|
1882
|
+
offset
|
|
1883
|
+
);
|
|
1884
|
+
const result = {
|
|
1885
|
+
success: true,
|
|
1886
|
+
snapshots,
|
|
1887
|
+
count: snapshots.length,
|
|
1888
|
+
totalCount: total
|
|
1889
|
+
};
|
|
1890
|
+
const tokenEstimate = Math.ceil(
|
|
1891
|
+
Buffer.byteLength(JSON.stringify(result), "utf8") / 4
|
|
1892
|
+
);
|
|
1893
|
+
return {
|
|
1894
|
+
content: [
|
|
1895
|
+
{
|
|
1896
|
+
type: "text",
|
|
1897
|
+
text: JSON.stringify(
|
|
1898
|
+
{ ...result, _meta: { tokenEstimate } },
|
|
1899
|
+
null,
|
|
1900
|
+
2
|
|
1901
|
+
)
|
|
1902
|
+
}
|
|
1903
|
+
],
|
|
1904
|
+
structuredContent: result
|
|
1905
|
+
};
|
|
1906
|
+
}
|
|
1907
|
+
);
|
|
1908
|
+
server.registerTool(
|
|
1909
|
+
"sqlite_audit_get_backup",
|
|
1910
|
+
{
|
|
1911
|
+
title: "Get Audit Backup",
|
|
1912
|
+
description: "Retrieve a specific pre-mutation DDL snapshot by filename. Returns the full snapshot content including DDL and optional data.",
|
|
1913
|
+
inputSchema: z.object({
|
|
1914
|
+
filename: z.string().default("").describe("Snapshot filename from sqlite_audit_list_backups results")
|
|
1915
|
+
}),
|
|
1916
|
+
outputSchema: AuditGetBackupOutputSchema,
|
|
1917
|
+
annotations: {
|
|
1918
|
+
readOnlyHint: true,
|
|
1919
|
+
destructiveHint: false,
|
|
1920
|
+
idempotentHint: true,
|
|
1921
|
+
openWorldHint: false
|
|
1922
|
+
}
|
|
1923
|
+
},
|
|
1924
|
+
async (args) => {
|
|
1925
|
+
const authCtx = getAuthContext();
|
|
1926
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "sqlite_audit_get_backup")) {
|
|
1927
|
+
throw new InsufficientScopeError(["admin", "full"], authCtx.scopes);
|
|
1928
|
+
}
|
|
1929
|
+
let filename;
|
|
1930
|
+
try {
|
|
1931
|
+
const parsed = z.object({ filename: z.string().min(1, "filename is required") }).parse(args);
|
|
1932
|
+
filename = parsed.filename;
|
|
1933
|
+
} catch (error) {
|
|
1934
|
+
const structured = formatHandlerError(error);
|
|
1935
|
+
return {
|
|
1936
|
+
content: [
|
|
1937
|
+
{
|
|
1938
|
+
type: "text",
|
|
1939
|
+
text: JSON.stringify(structured, null, 2)
|
|
1940
|
+
}
|
|
1941
|
+
],
|
|
1942
|
+
isError: true,
|
|
1943
|
+
structuredContent: structured
|
|
1944
|
+
};
|
|
1945
|
+
}
|
|
1946
|
+
const snapshot = await backupManager.getSnapshot(filename);
|
|
1947
|
+
if (!snapshot) {
|
|
1948
|
+
const errRes = {
|
|
1949
|
+
success: false,
|
|
1950
|
+
error: `Snapshot not found: ${filename}`
|
|
1951
|
+
};
|
|
1952
|
+
return {
|
|
1953
|
+
content: [
|
|
1954
|
+
{
|
|
1955
|
+
type: "text",
|
|
1956
|
+
text: JSON.stringify(errRes, null, 2)
|
|
1957
|
+
}
|
|
1958
|
+
],
|
|
1959
|
+
isError: true,
|
|
1960
|
+
structuredContent: errRes
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
const result = { success: true, ...snapshot };
|
|
1964
|
+
const snapshotStr = JSON.stringify(result, null, 2);
|
|
1965
|
+
return {
|
|
1966
|
+
content: [
|
|
1967
|
+
{
|
|
1968
|
+
type: "text",
|
|
1969
|
+
text: redactSqlLiterals(snapshotStr)
|
|
1970
|
+
}
|
|
1971
|
+
],
|
|
1972
|
+
structuredContent: result
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
);
|
|
1976
|
+
server.registerTool(
|
|
1977
|
+
"sqlite_audit_cleanup",
|
|
1978
|
+
{
|
|
1979
|
+
title: "Cleanup Audit Backups",
|
|
1980
|
+
description: "Apply retention policy to audit backup snapshots. Deletes snapshots exceeding age or count limits.",
|
|
1981
|
+
outputSchema: AuditCleanupOutputSchema,
|
|
1982
|
+
annotations: {
|
|
1983
|
+
readOnlyHint: false,
|
|
1984
|
+
destructiveHint: true,
|
|
1985
|
+
idempotentHint: true,
|
|
1986
|
+
openWorldHint: false
|
|
1987
|
+
}
|
|
1988
|
+
},
|
|
1989
|
+
async () => {
|
|
1990
|
+
const authCtx = getAuthContext();
|
|
1991
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "sqlite_audit_cleanup")) {
|
|
1992
|
+
throw new InsufficientScopeError(["admin", "full"], authCtx.scopes);
|
|
1993
|
+
}
|
|
1994
|
+
const deleted = await backupManager.cleanup();
|
|
1995
|
+
const result = {
|
|
1996
|
+
success: true,
|
|
1997
|
+
deletedCount: deleted,
|
|
1998
|
+
message: deleted > 0 ? `Cleaned up ${String(deleted)} snapshot(s)` : "No snapshots to clean up"
|
|
1999
|
+
};
|
|
2000
|
+
return {
|
|
2001
|
+
content: [
|
|
2002
|
+
{
|
|
2003
|
+
type: "text",
|
|
2004
|
+
text: JSON.stringify(result, null, 2)
|
|
2005
|
+
}
|
|
2006
|
+
],
|
|
2007
|
+
structuredContent: result
|
|
2008
|
+
};
|
|
2009
|
+
}
|
|
2010
|
+
);
|
|
2011
|
+
server.registerTool(
|
|
2012
|
+
"sqlite_audit_diff_backup",
|
|
2013
|
+
{
|
|
2014
|
+
title: "Diff Audit Backup",
|
|
2015
|
+
description: "Compare a pre-mutation DDL snapshot against the live database schema. Shows objects that have been added, removed, or modified since the snapshot was taken.",
|
|
2016
|
+
inputSchema: z.object({
|
|
2017
|
+
filename: z.string().default("").describe(
|
|
2018
|
+
"Snapshot filename to compare against the live database schema"
|
|
2019
|
+
)
|
|
2020
|
+
}),
|
|
2021
|
+
outputSchema: AuditDiffBackupOutputSchema,
|
|
2022
|
+
annotations: {
|
|
2023
|
+
readOnlyHint: true,
|
|
2024
|
+
destructiveHint: false,
|
|
2025
|
+
idempotentHint: true,
|
|
2026
|
+
openWorldHint: false
|
|
2027
|
+
}
|
|
2028
|
+
},
|
|
2029
|
+
async (args) => {
|
|
2030
|
+
const authCtx = getAuthContext();
|
|
2031
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "sqlite_audit_diff_backup")) {
|
|
2032
|
+
throw new InsufficientScopeError(["admin", "full"], authCtx.scopes);
|
|
2033
|
+
}
|
|
2034
|
+
let filename;
|
|
2035
|
+
try {
|
|
2036
|
+
const parsed = z.object({ filename: z.string().min(1, "filename is required") }).parse(args);
|
|
2037
|
+
filename = parsed.filename;
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
const structured = formatHandlerError(error);
|
|
2040
|
+
return {
|
|
2041
|
+
content: [
|
|
2042
|
+
{
|
|
2043
|
+
type: "text",
|
|
2044
|
+
text: JSON.stringify(structured, null, 2)
|
|
2045
|
+
}
|
|
2046
|
+
],
|
|
2047
|
+
isError: true,
|
|
2048
|
+
structuredContent: structured
|
|
2049
|
+
};
|
|
2050
|
+
}
|
|
2051
|
+
const snapshot = await backupManager.getSnapshot(filename);
|
|
2052
|
+
if (!snapshot) {
|
|
2053
|
+
const errRes = {
|
|
2054
|
+
success: false,
|
|
2055
|
+
error: `Snapshot not found: ${filename}`
|
|
2056
|
+
};
|
|
2057
|
+
return {
|
|
2058
|
+
content: [
|
|
2059
|
+
{
|
|
2060
|
+
type: "text",
|
|
2061
|
+
text: JSON.stringify(errRes, null, 2)
|
|
2062
|
+
}
|
|
2063
|
+
],
|
|
2064
|
+
isError: true,
|
|
2065
|
+
structuredContent: errRes
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
const adapter = [...adaptersMap.values()][0];
|
|
2069
|
+
if (!adapter) {
|
|
2070
|
+
const errRes = {
|
|
2071
|
+
success: false,
|
|
2072
|
+
error: "No connected adapter available"
|
|
2073
|
+
};
|
|
2074
|
+
return {
|
|
2075
|
+
content: [
|
|
2076
|
+
{
|
|
2077
|
+
type: "text",
|
|
2078
|
+
text: JSON.stringify(errRes, null, 2)
|
|
2079
|
+
}
|
|
2080
|
+
],
|
|
2081
|
+
isError: true,
|
|
2082
|
+
structuredContent: errRes
|
|
2083
|
+
};
|
|
2084
|
+
}
|
|
2085
|
+
try {
|
|
2086
|
+
const liveResult = await adapter.executeReadQuery(
|
|
2087
|
+
"SELECT name, type, sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY type, name"
|
|
2088
|
+
);
|
|
2089
|
+
const liveObjects = /* @__PURE__ */ new Map();
|
|
2090
|
+
for (const row of liveResult.rows ?? []) {
|
|
2091
|
+
liveObjects.set(row["name"], {
|
|
2092
|
+
type: row["type"],
|
|
2093
|
+
sql: row["sql"]
|
|
2094
|
+
});
|
|
2095
|
+
}
|
|
2096
|
+
const snapshotDdl = snapshot.ddl ?? "";
|
|
2097
|
+
const snapshotObjects = /* @__PURE__ */ new Map();
|
|
2098
|
+
const statements = snapshotDdl.split(";").map((s) => s.trim()).filter(Boolean);
|
|
2099
|
+
for (const stmt of statements) {
|
|
2100
|
+
const match = /CREATE\s+(?:VIRTUAL\s+)?(?:TEMP(?:ORARY)?\s+)?(TABLE|INDEX|VIEW|TRIGGER)\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:"([^"]+)"|(\S+))/i.exec(
|
|
2101
|
+
stmt
|
|
2102
|
+
);
|
|
2103
|
+
if (match) {
|
|
2104
|
+
const type = (match[1] ?? "").toLowerCase();
|
|
2105
|
+
const name = match[2] ?? match[3] ?? "";
|
|
2106
|
+
snapshotObjects.set(name, { type, sql: stmt });
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
const diffs = [];
|
|
2110
|
+
const snapshotTarget = snapshot.metadata?.target;
|
|
2111
|
+
for (const [name, live] of liveObjects) {
|
|
2112
|
+
if (name === snapshotTarget || snapshotObjects.has(name)) {
|
|
2113
|
+
if (!snapshotObjects.has(name)) {
|
|
2114
|
+
diffs.push({
|
|
2115
|
+
object: name,
|
|
2116
|
+
type: live.type,
|
|
2117
|
+
status: "added",
|
|
2118
|
+
liveDefinition: live.sql
|
|
2119
|
+
});
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
for (const [name, snap] of snapshotObjects) {
|
|
2124
|
+
if (!liveObjects.has(name)) {
|
|
2125
|
+
diffs.push({
|
|
2126
|
+
object: name,
|
|
2127
|
+
type: snap.type,
|
|
2128
|
+
status: "removed",
|
|
2129
|
+
snapshotDefinition: snap.sql
|
|
2130
|
+
});
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
for (const [name, snap] of snapshotObjects) {
|
|
2134
|
+
const live = liveObjects.get(name);
|
|
2135
|
+
if (live && live.sql !== snap.sql) {
|
|
2136
|
+
diffs.push({
|
|
2137
|
+
object: name,
|
|
2138
|
+
type: live.type,
|
|
2139
|
+
status: "modified",
|
|
2140
|
+
liveDefinition: live.sql,
|
|
2141
|
+
snapshotDefinition: snap.sql
|
|
2142
|
+
});
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
const result = {
|
|
2146
|
+
success: true,
|
|
2147
|
+
diffs,
|
|
2148
|
+
snapshotTimestamp: snapshot.metadata?.timestamp ?? "",
|
|
2149
|
+
snapshotTarget: snapshot.metadata?.target ?? ""
|
|
2150
|
+
};
|
|
2151
|
+
return {
|
|
2152
|
+
content: [
|
|
2153
|
+
{
|
|
2154
|
+
type: "text",
|
|
2155
|
+
text: JSON.stringify(result, null, 2)
|
|
2156
|
+
}
|
|
2157
|
+
],
|
|
2158
|
+
structuredContent: result
|
|
2159
|
+
};
|
|
2160
|
+
} catch (error) {
|
|
2161
|
+
const errRes = {
|
|
2162
|
+
success: false,
|
|
2163
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2164
|
+
};
|
|
2165
|
+
return {
|
|
2166
|
+
content: [
|
|
2167
|
+
{
|
|
2168
|
+
type: "text",
|
|
2169
|
+
text: JSON.stringify(errRes, null, 2)
|
|
2170
|
+
}
|
|
2171
|
+
],
|
|
2172
|
+
isError: true,
|
|
2173
|
+
structuredContent: errRes
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
);
|
|
2178
|
+
server.registerTool(
|
|
2179
|
+
"sqlite_audit_restore_backup",
|
|
2180
|
+
{
|
|
2181
|
+
title: "Restore Audit Backup",
|
|
2182
|
+
description: "Restore a pre-mutation DDL snapshot by executing its DDL statements against the live database. Use dryRun=true to preview the DDL without applying changes.",
|
|
2183
|
+
inputSchema: z.object({
|
|
2184
|
+
filename: z.string().default("").describe("Snapshot filename to restore from"),
|
|
2185
|
+
dryRun: z.unknown().optional().describe("If true, returns the DDL without executing it (boolean)")
|
|
2186
|
+
}),
|
|
2187
|
+
outputSchema: AuditRestoreBackupOutputSchema,
|
|
2188
|
+
annotations: {
|
|
2189
|
+
readOnlyHint: false,
|
|
2190
|
+
destructiveHint: true,
|
|
2191
|
+
idempotentHint: false,
|
|
2192
|
+
openWorldHint: false
|
|
2193
|
+
}
|
|
2194
|
+
},
|
|
2195
|
+
async (args) => {
|
|
2196
|
+
const authCtx = getAuthContext();
|
|
2197
|
+
if (authCtx && !scopesGrantToolAccess(authCtx.scopes, "sqlite_audit_restore_backup")) {
|
|
2198
|
+
throw new InsufficientScopeError(["admin", "full"], authCtx.scopes);
|
|
2199
|
+
}
|
|
2200
|
+
let filename;
|
|
2201
|
+
let dryRun;
|
|
2202
|
+
try {
|
|
2203
|
+
const parsed = z.object({
|
|
2204
|
+
filename: z.string().min(1, "filename is required"),
|
|
2205
|
+
dryRun: z.boolean().optional().default(false)
|
|
2206
|
+
}).parse(args);
|
|
2207
|
+
filename = parsed.filename;
|
|
2208
|
+
dryRun = parsed.dryRun;
|
|
2209
|
+
} catch (error) {
|
|
2210
|
+
const structured = formatHandlerError(error);
|
|
2211
|
+
return {
|
|
2212
|
+
content: [
|
|
2213
|
+
{
|
|
2214
|
+
type: "text",
|
|
2215
|
+
text: JSON.stringify(structured, null, 2)
|
|
2216
|
+
}
|
|
2217
|
+
],
|
|
2218
|
+
isError: true,
|
|
2219
|
+
structuredContent: structured
|
|
2220
|
+
};
|
|
2221
|
+
}
|
|
2222
|
+
const snapshot = await backupManager.getSnapshot(filename);
|
|
2223
|
+
if (!snapshot) {
|
|
2224
|
+
const errRes = {
|
|
2225
|
+
success: false,
|
|
2226
|
+
error: `Snapshot not found: ${filename}`
|
|
2227
|
+
};
|
|
2228
|
+
return {
|
|
2229
|
+
content: [
|
|
2230
|
+
{
|
|
2231
|
+
type: "text",
|
|
2232
|
+
text: JSON.stringify(errRes, null, 2)
|
|
2233
|
+
}
|
|
2234
|
+
],
|
|
2235
|
+
isError: true,
|
|
2236
|
+
structuredContent: errRes
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2239
|
+
const ddl = snapshot.ddl ?? "";
|
|
2240
|
+
if (!ddl.trim()) {
|
|
2241
|
+
const errRes = {
|
|
2242
|
+
success: false,
|
|
2243
|
+
error: "Snapshot contains no DDL statements"
|
|
2244
|
+
};
|
|
2245
|
+
return {
|
|
2246
|
+
content: [
|
|
2247
|
+
{
|
|
2248
|
+
type: "text",
|
|
2249
|
+
text: JSON.stringify(errRes, null, 2)
|
|
2250
|
+
}
|
|
2251
|
+
],
|
|
2252
|
+
isError: true,
|
|
2253
|
+
structuredContent: errRes
|
|
2254
|
+
};
|
|
2255
|
+
}
|
|
2256
|
+
const adapter = [...adaptersMap.values()][0];
|
|
2257
|
+
if (!adapter) {
|
|
2258
|
+
const errRes = {
|
|
2259
|
+
success: false,
|
|
2260
|
+
error: "No connected adapter available"
|
|
2261
|
+
};
|
|
2262
|
+
return {
|
|
2263
|
+
content: [
|
|
2264
|
+
{
|
|
2265
|
+
type: "text",
|
|
2266
|
+
text: JSON.stringify(errRes, null, 2)
|
|
2267
|
+
}
|
|
2268
|
+
],
|
|
2269
|
+
isError: true,
|
|
2270
|
+
structuredContent: errRes
|
|
2271
|
+
};
|
|
2272
|
+
}
|
|
2273
|
+
if (dryRun) {
|
|
2274
|
+
const result = {
|
|
2275
|
+
success: true,
|
|
2276
|
+
message: "Dry run: no changes applied",
|
|
2277
|
+
dryRun: true,
|
|
2278
|
+
ddl: redactSqlLiterals(ddl)
|
|
2279
|
+
};
|
|
2280
|
+
return {
|
|
2281
|
+
content: [
|
|
2282
|
+
{
|
|
2283
|
+
type: "text",
|
|
2284
|
+
text: JSON.stringify(result, null, 2)
|
|
2285
|
+
}
|
|
2286
|
+
],
|
|
2287
|
+
structuredContent: result
|
|
2288
|
+
};
|
|
2289
|
+
}
|
|
2290
|
+
try {
|
|
2291
|
+
const statements = ddl.split(";").map((s) => s.trim()).filter((s) => {
|
|
2292
|
+
const cleanSql = s.replace(/\/\*[\s\S]*?\*\//g, "").replace(/--.*$/gm, "").trim();
|
|
2293
|
+
return cleanSql.length > 0;
|
|
2294
|
+
});
|
|
2295
|
+
if (statements.length === 0) {
|
|
2296
|
+
const result2 = {
|
|
2297
|
+
success: true,
|
|
2298
|
+
message: "No executable statements found in snapshot (only comments)",
|
|
2299
|
+
changesApplied: 0
|
|
2300
|
+
};
|
|
2301
|
+
return {
|
|
2302
|
+
content: [
|
|
2303
|
+
{
|
|
2304
|
+
type: "text",
|
|
2305
|
+
text: JSON.stringify(result2, null, 2)
|
|
2306
|
+
}
|
|
2307
|
+
],
|
|
2308
|
+
structuredContent: result2
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2311
|
+
await adapter.executeQuery("BEGIN TRANSACTION;");
|
|
2312
|
+
try {
|
|
2313
|
+
for (const stmt of statements) {
|
|
2314
|
+
validateDdl(stmt);
|
|
2315
|
+
await adapter.executeQuery(`${stmt};`);
|
|
2316
|
+
}
|
|
2317
|
+
await adapter.executeQuery("COMMIT;");
|
|
2318
|
+
} catch (e) {
|
|
2319
|
+
await adapter.executeQuery("ROLLBACK;");
|
|
2320
|
+
throw e;
|
|
2321
|
+
}
|
|
2322
|
+
const result = {
|
|
2323
|
+
success: true,
|
|
2324
|
+
message: `Successfully executed ${statements.length} statement(s) from snapshot`,
|
|
2325
|
+
changesApplied: statements.length
|
|
2326
|
+
};
|
|
2327
|
+
return {
|
|
2328
|
+
content: [
|
|
2329
|
+
{
|
|
2330
|
+
type: "text",
|
|
2331
|
+
text: JSON.stringify(result, null, 2)
|
|
2332
|
+
}
|
|
2333
|
+
],
|
|
2334
|
+
structuredContent: result
|
|
2335
|
+
};
|
|
2336
|
+
} catch (error) {
|
|
2337
|
+
const errRes = {
|
|
2338
|
+
success: false,
|
|
2339
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2340
|
+
};
|
|
2341
|
+
return {
|
|
2342
|
+
content: [
|
|
2343
|
+
{
|
|
2344
|
+
type: "text",
|
|
2345
|
+
text: JSON.stringify(errRes, null, 2)
|
|
2346
|
+
}
|
|
2347
|
+
],
|
|
2348
|
+
isError: true,
|
|
2349
|
+
structuredContent: errRes
|
|
2350
|
+
};
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
);
|
|
2354
|
+
registerToolScopes(
|
|
2355
|
+
/* @__PURE__ */ new Map([
|
|
2356
|
+
["sqlite_audit_list_backups", ["admin", "full"]],
|
|
2357
|
+
["sqlite_audit_get_backup", ["admin", "full"]],
|
|
2358
|
+
["sqlite_audit_cleanup", ["admin", "full"]],
|
|
2359
|
+
["sqlite_audit_diff_backup", ["admin", "full"]],
|
|
2360
|
+
["sqlite_audit_restore_backup", ["admin", "full"]]
|
|
2361
|
+
])
|
|
2362
|
+
);
|
|
2363
|
+
logger.info(
|
|
2364
|
+
"Registered audit backup tools: sqlite_audit_list_backups, sqlite_audit_get_backup, sqlite_audit_cleanup, sqlite_audit_diff_backup, sqlite_audit_restore_backup",
|
|
2365
|
+
{ module: "AUDIT" }
|
|
2366
|
+
);
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
// src/server/mcp-server.ts
|
|
2370
|
+
var proto = McpServer.prototype;
|
|
2371
|
+
if (typeof proto["createToolError"] === "function") {
|
|
2372
|
+
const originalCreateToolError = proto["createToolError"];
|
|
2373
|
+
proto["createToolError"] = function(errorMessage) {
|
|
2374
|
+
const result = originalCreateToolError.call(
|
|
2375
|
+
this,
|
|
2376
|
+
errorMessage
|
|
2377
|
+
);
|
|
2378
|
+
if (result.content?.[0]?.type === "text") {
|
|
2379
|
+
const rawError = result.content[0].text;
|
|
2380
|
+
if (rawError.includes("Input validation error")) {
|
|
2381
|
+
const cleanError = rawError.replace(
|
|
2382
|
+
/^MCP error -32602: Input validation error: /,
|
|
2383
|
+
"Validation error: "
|
|
2384
|
+
);
|
|
2385
|
+
const structured = {
|
|
2386
|
+
success: false,
|
|
2387
|
+
error: cleanError,
|
|
2388
|
+
code: "VALIDATION_ERROR",
|
|
2389
|
+
category: "validation" /* VALIDATION */
|
|
2390
|
+
};
|
|
2391
|
+
result.content[0].text = JSON.stringify(structured, null, 2);
|
|
2392
|
+
result.isError = true;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
return result;
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
1507
2398
|
var DbMcpServer = class {
|
|
1508
2399
|
server;
|
|
1509
2400
|
adapters = /* @__PURE__ */ new Map();
|
|
@@ -1536,8 +2427,35 @@ var DbMcpServer = class {
|
|
|
1536
2427
|
toolFilter: config.toolFilter ?? "none",
|
|
1537
2428
|
capabilities: ["logging"]
|
|
1538
2429
|
});
|
|
1539
|
-
|
|
1540
|
-
|
|
2430
|
+
registerBuiltInTools(
|
|
2431
|
+
this.server,
|
|
2432
|
+
this.adapters,
|
|
2433
|
+
this.config,
|
|
2434
|
+
this.toolFilter
|
|
2435
|
+
);
|
|
2436
|
+
registerHelpResources(this.server, this.toolFilter);
|
|
2437
|
+
const internalMcp = this.server;
|
|
2438
|
+
const handlers = internalMcp.server._requestHandlers;
|
|
2439
|
+
if (!handlers?.has("tools/list")) {
|
|
2440
|
+
throw new DbMcpError(
|
|
2441
|
+
"Security: SDK _requestHandlers monkey-patch failed. Scope filtering is disabled.",
|
|
2442
|
+
"SERVER_START_FAILED",
|
|
2443
|
+
"internal" /* INTERNAL */
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
const originalListToolsHandler = handlers.get("tools/list");
|
|
2447
|
+
if (originalListToolsHandler) {
|
|
2448
|
+
handlers.set("tools/list", async (request, extra) => {
|
|
2449
|
+
const result = await originalListToolsHandler(request, extra);
|
|
2450
|
+
const authCtx = getAuthContext();
|
|
2451
|
+
if (authCtx && Array.isArray(result.tools)) {
|
|
2452
|
+
result.tools = result.tools.filter(
|
|
2453
|
+
(t) => scopesGrantToolAccess(authCtx.scopes, t.name)
|
|
2454
|
+
);
|
|
2455
|
+
}
|
|
2456
|
+
return result;
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
1541
2459
|
if (config.audit?.enabled) {
|
|
1542
2460
|
this.auditInitPromise = this.initializeAudit(config);
|
|
1543
2461
|
}
|
|
@@ -1554,6 +2472,9 @@ var DbMcpServer = class {
|
|
|
1554
2472
|
this.adapters.set(adapterId, adapter);
|
|
1555
2473
|
if (this.auditInterceptor && "setAuditInterceptor" in adapter) {
|
|
1556
2474
|
adapter.setAuditInterceptor(this.auditInterceptor);
|
|
2475
|
+
this.auditInterceptor.setQueryAdapter({
|
|
2476
|
+
executeQuery: (sql, params) => adapter.executeReadQuery(sql, params)
|
|
2477
|
+
});
|
|
1557
2478
|
}
|
|
1558
2479
|
if (this.backupManager && "setBackupManager" in adapter) {
|
|
1559
2480
|
adapter.setBackupManager(this.backupManager);
|
|
@@ -1561,6 +2482,15 @@ var DbMcpServer = class {
|
|
|
1561
2482
|
adapter.registerTools(this.server, this.toolFilter);
|
|
1562
2483
|
adapter.registerResources(this.server);
|
|
1563
2484
|
adapter.registerPrompts(this.server);
|
|
2485
|
+
const toolDefs = adapter.getToolDefinitions();
|
|
2486
|
+
const scopesMap = /* @__PURE__ */ new Map();
|
|
2487
|
+
for (const tool of toolDefs) {
|
|
2488
|
+
if (tool.requiredScopes) {
|
|
2489
|
+
scopesMap.set(tool.name, tool.requiredScopes);
|
|
2490
|
+
scopesMap.set(`sqlite_${tool.name}`, tool.requiredScopes);
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
registerToolScopes(scopesMap);
|
|
1564
2494
|
logger.info(`Registered adapter: ${adapter.name} (${adapterId})`, {
|
|
1565
2495
|
module: "SERVER"
|
|
1566
2496
|
});
|
|
@@ -1577,178 +2507,6 @@ var DbMcpServer = class {
|
|
|
1577
2507
|
getAdapters() {
|
|
1578
2508
|
return this.adapters;
|
|
1579
2509
|
}
|
|
1580
|
-
/**
|
|
1581
|
-
* Register built-in server tools (health, info, etc.)
|
|
1582
|
-
*/
|
|
1583
|
-
registerBuiltInTools() {
|
|
1584
|
-
const serverInfoOpts = {
|
|
1585
|
-
title: "Server Info",
|
|
1586
|
-
description: "Get information about the db-mcp server and registered adapters",
|
|
1587
|
-
icons: SERVER_ICONS,
|
|
1588
|
-
annotations: READ_ONLY
|
|
1589
|
-
};
|
|
1590
|
-
this.server.registerTool("server_info", serverInfoOpts, () => {
|
|
1591
|
-
const adapterInfo = [];
|
|
1592
|
-
for (const [id, adapter] of this.adapters) {
|
|
1593
|
-
adapterInfo.push({
|
|
1594
|
-
id,
|
|
1595
|
-
...adapter.getInfo()
|
|
1596
|
-
});
|
|
1597
|
-
}
|
|
1598
|
-
return {
|
|
1599
|
-
content: [
|
|
1600
|
-
{
|
|
1601
|
-
type: "text",
|
|
1602
|
-
text: JSON.stringify(
|
|
1603
|
-
{
|
|
1604
|
-
name: this.config.name,
|
|
1605
|
-
version: this.config.version,
|
|
1606
|
-
transport: this.config.transport,
|
|
1607
|
-
adapters: adapterInfo,
|
|
1608
|
-
toolFilter: {
|
|
1609
|
-
raw: this.toolFilter.raw,
|
|
1610
|
-
enabledGroups: [...this.toolFilter.enabledGroups]
|
|
1611
|
-
}
|
|
1612
|
-
},
|
|
1613
|
-
null,
|
|
1614
|
-
2
|
|
1615
|
-
)
|
|
1616
|
-
}
|
|
1617
|
-
]
|
|
1618
|
-
};
|
|
1619
|
-
});
|
|
1620
|
-
const healthOpts = {
|
|
1621
|
-
title: "Server Health",
|
|
1622
|
-
description: "Check health status of all database connections",
|
|
1623
|
-
icons: SERVER_ICONS,
|
|
1624
|
-
annotations: READ_ONLY
|
|
1625
|
-
};
|
|
1626
|
-
this.server.registerTool("server_health", healthOpts, async () => {
|
|
1627
|
-
const health = {
|
|
1628
|
-
server: "healthy",
|
|
1629
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1630
|
-
adapters: {}
|
|
1631
|
-
};
|
|
1632
|
-
for (const [id, adapter] of this.adapters) {
|
|
1633
|
-
try {
|
|
1634
|
-
const adapterHealth = await adapter.getHealth();
|
|
1635
|
-
health["adapters"][id] = adapterHealth;
|
|
1636
|
-
} catch (error) {
|
|
1637
|
-
health["adapters"][id] = {
|
|
1638
|
-
connected: false,
|
|
1639
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
1640
|
-
};
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
return {
|
|
1644
|
-
content: [
|
|
1645
|
-
{
|
|
1646
|
-
type: "text",
|
|
1647
|
-
text: JSON.stringify(health, null, 2)
|
|
1648
|
-
}
|
|
1649
|
-
]
|
|
1650
|
-
};
|
|
1651
|
-
});
|
|
1652
|
-
const listAdaptersOpts = {
|
|
1653
|
-
title: "List Adapters",
|
|
1654
|
-
description: "List all registered database adapters",
|
|
1655
|
-
icons: SERVER_ICONS,
|
|
1656
|
-
annotations: READ_ONLY
|
|
1657
|
-
};
|
|
1658
|
-
this.server.registerTool("list_adapters", listAdaptersOpts, () => {
|
|
1659
|
-
const adapters = [];
|
|
1660
|
-
for (const [id, adapter] of this.adapters) {
|
|
1661
|
-
adapters.push({
|
|
1662
|
-
id,
|
|
1663
|
-
type: adapter.type,
|
|
1664
|
-
name: adapter.name,
|
|
1665
|
-
version: adapter.version,
|
|
1666
|
-
connected: adapter.isConnected()
|
|
1667
|
-
});
|
|
1668
|
-
}
|
|
1669
|
-
return {
|
|
1670
|
-
content: [
|
|
1671
|
-
{
|
|
1672
|
-
type: "text",
|
|
1673
|
-
text: JSON.stringify(adapters, null, 2)
|
|
1674
|
-
}
|
|
1675
|
-
]
|
|
1676
|
-
};
|
|
1677
|
-
});
|
|
1678
|
-
}
|
|
1679
|
-
/**
|
|
1680
|
-
* Register sqlite://help resources for on-demand reference documentation.
|
|
1681
|
-
* Always registers sqlite://help (gotchas). Group-specific help is filtered
|
|
1682
|
-
* by the tool filter configuration.
|
|
1683
|
-
*/
|
|
1684
|
-
registerHelpResources() {
|
|
1685
|
-
const gotchasContent = HELP_CONTENT.get("gotchas");
|
|
1686
|
-
if (gotchasContent) {
|
|
1687
|
-
this.server.registerResource(
|
|
1688
|
-
"sqlite_help",
|
|
1689
|
-
"sqlite://help",
|
|
1690
|
-
{
|
|
1691
|
-
description: "Critical gotchas, WASM vs Native comparison, and Code Mode API reference",
|
|
1692
|
-
mimeType: "text/markdown"
|
|
1693
|
-
},
|
|
1694
|
-
() => ({
|
|
1695
|
-
contents: [
|
|
1696
|
-
{
|
|
1697
|
-
uri: "sqlite://help",
|
|
1698
|
-
mimeType: "text/markdown",
|
|
1699
|
-
text: gotchasContent
|
|
1700
|
-
}
|
|
1701
|
-
]
|
|
1702
|
-
})
|
|
1703
|
-
);
|
|
1704
|
-
}
|
|
1705
|
-
const groupHelpKeys = [
|
|
1706
|
-
{ group: "core", key: "core" },
|
|
1707
|
-
{ group: "json", key: "json" },
|
|
1708
|
-
{ group: "text", key: "text" },
|
|
1709
|
-
{ group: "stats", key: "stats" },
|
|
1710
|
-
{ group: "vector", key: "vector" },
|
|
1711
|
-
{ group: "geo", key: "geo" },
|
|
1712
|
-
{ group: "admin", key: "admin" },
|
|
1713
|
-
{ group: "transactions", key: "transactions" },
|
|
1714
|
-
{ group: "introspection", key: "introspection" },
|
|
1715
|
-
{ group: "migration", key: "migration" }
|
|
1716
|
-
];
|
|
1717
|
-
for (const { group, key } of groupHelpKeys) {
|
|
1718
|
-
const isCodemodeOnly = this.toolFilter.enabledGroups.size === 1 && this.toolFilter.enabledGroups.has("codemode");
|
|
1719
|
-
if (!this.toolFilter.enabledGroups.has(group) && !isCodemodeOnly) {
|
|
1720
|
-
continue;
|
|
1721
|
-
}
|
|
1722
|
-
const content = HELP_CONTENT.get(key);
|
|
1723
|
-
if (!content) continue;
|
|
1724
|
-
this.server.registerResource(
|
|
1725
|
-
`sqlite_help_${key}`,
|
|
1726
|
-
`sqlite://help/${key}`,
|
|
1727
|
-
{
|
|
1728
|
-
description: `Tool reference for the ${group} tool group`,
|
|
1729
|
-
mimeType: "text/markdown"
|
|
1730
|
-
},
|
|
1731
|
-
() => ({
|
|
1732
|
-
contents: [
|
|
1733
|
-
{
|
|
1734
|
-
uri: `sqlite://help/${key}`,
|
|
1735
|
-
mimeType: "text/markdown",
|
|
1736
|
-
text: content
|
|
1737
|
-
}
|
|
1738
|
-
]
|
|
1739
|
-
})
|
|
1740
|
-
);
|
|
1741
|
-
}
|
|
1742
|
-
const registeredHelp = ["sqlite://help"];
|
|
1743
|
-
for (const { group, key } of groupHelpKeys) {
|
|
1744
|
-
if (this.toolFilter.enabledGroups.has(group)) {
|
|
1745
|
-
registeredHelp.push(`sqlite://help/${key}`);
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
logger.info(`Help resources: ${registeredHelp.join(", ")}`, {
|
|
1749
|
-
module: "SERVER"
|
|
1750
|
-
});
|
|
1751
|
-
}
|
|
1752
2510
|
/**
|
|
1753
2511
|
* Start the server with the configured transport
|
|
1754
2512
|
*/
|
|
@@ -1777,12 +2535,16 @@ var DbMcpServer = class {
|
|
|
1777
2535
|
logger.info(`db-mcp server started (stdio transport)`, {
|
|
1778
2536
|
module: "SERVER"
|
|
1779
2537
|
});
|
|
2538
|
+
logger.warning(
|
|
2539
|
+
"SECURITY WARNING: Running in STDIO mode grants blanket 'admin' access to all tools. This implies full trust in the local client/agent. If this server is exposed over SSH or used by an untrusted client, consider using HTTP transport with OAuth (--oauth-enabled) for granular scope enforcement.",
|
|
2540
|
+
{ module: "SERVER", code: "STDIO_ADMIN_RISK" }
|
|
2541
|
+
);
|
|
1780
2542
|
}
|
|
1781
2543
|
/**
|
|
1782
2544
|
* Start server with HTTP transport (Streamable HTTP with SSE support)
|
|
1783
2545
|
*/
|
|
1784
2546
|
async startHttp() {
|
|
1785
|
-
const { HttpTransport } = await import('./http-
|
|
2547
|
+
const { HttpTransport } = await import('./http-HWTUVFIA.js');
|
|
1786
2548
|
const oauthConfig = {
|
|
1787
2549
|
enabled: this.config.oauth?.enabled ?? false,
|
|
1788
2550
|
authorizationServerUrl: this.config.oauth?.authorizationServerUrl ?? "",
|
|
@@ -1810,12 +2572,13 @@ var DbMcpServer = class {
|
|
|
1810
2572
|
enableHSTS: this.config.enableHSTS
|
|
1811
2573
|
},
|
|
1812
2574
|
oauth: oauthConfig,
|
|
1813
|
-
stateless: this.config.statelessHttp ?? false
|
|
2575
|
+
stateless: this.config.statelessHttp ?? false,
|
|
2576
|
+
noAuthEnforcement: this.config.noAuthEnforcement ?? false
|
|
1814
2577
|
});
|
|
1815
2578
|
await transport.initialize(this.server);
|
|
1816
2579
|
await transport.start();
|
|
1817
2580
|
const mode = this.config.statelessHttp ? "stateless" : "stateful";
|
|
1818
|
-
const host = this.config.host ?? "
|
|
2581
|
+
const host = this.config.host ?? "127.0.0.1";
|
|
1819
2582
|
const port = String(this.config.port ?? 3e3);
|
|
1820
2583
|
logger.info(
|
|
1821
2584
|
`db-mcp server started (HTTP transport on ${host}:${port}, ${mode} mode)`,
|
|
@@ -1866,179 +2629,17 @@ var DbMcpServer = class {
|
|
|
1866
2629
|
}
|
|
1867
2630
|
this.auditInterceptor = createAuditInterceptor(
|
|
1868
2631
|
this.auditLogger,
|
|
1869
|
-
this.backupManager ?? void 0
|
|
1870
|
-
|
|
2632
|
+
this.backupManager ?? void 0
|
|
2633
|
+
);
|
|
2634
|
+
registerAuditResource(this.server, this.auditLogger, this.backupManager);
|
|
1871
2635
|
if (this.backupManager && this.toolFilter.enabledGroups.has("admin")) {
|
|
1872
|
-
this.
|
|
2636
|
+
registerAuditBackupTools(this.server, this.backupManager, this.adapters);
|
|
1873
2637
|
}
|
|
1874
2638
|
logger.info(
|
|
1875
2639
|
`Audit logging enabled (${auditConfig.logPath}, redact=${String(auditConfig.redact)}, reads=${String(auditConfig.auditReads)}, backup=${String(!!auditConfig.backup?.enabled)})`,
|
|
1876
2640
|
{ module: "AUDIT" }
|
|
1877
2641
|
);
|
|
1878
2642
|
}
|
|
1879
|
-
/**
|
|
1880
|
-
* Register the sqlite://audit resource for agent access to audit log.
|
|
1881
|
-
*/
|
|
1882
|
-
registerAuditResource() {
|
|
1883
|
-
if (!this.auditLogger) return;
|
|
1884
|
-
const auditLogger = this.auditLogger;
|
|
1885
|
-
const backupManager = this.backupManager;
|
|
1886
|
-
this.server.registerResource(
|
|
1887
|
-
"sqlite_audit",
|
|
1888
|
-
"sqlite://audit",
|
|
1889
|
-
{
|
|
1890
|
-
description: "Recent audit log entries and backup statistics. Shows the last 50 tool invocations with timing, outcomes, and token estimates.",
|
|
1891
|
-
mimeType: "application/json"
|
|
1892
|
-
},
|
|
1893
|
-
async () => {
|
|
1894
|
-
const recent = await auditLogger.recent(50);
|
|
1895
|
-
const backupStats = backupManager ? await backupManager.getStats() : void 0;
|
|
1896
|
-
const payload = {
|
|
1897
|
-
entries: recent,
|
|
1898
|
-
stats: {
|
|
1899
|
-
totalEntries: recent.length,
|
|
1900
|
-
...backupStats && { backups: backupStats }
|
|
1901
|
-
}
|
|
1902
|
-
};
|
|
1903
|
-
return {
|
|
1904
|
-
contents: [
|
|
1905
|
-
{
|
|
1906
|
-
uri: "sqlite://audit",
|
|
1907
|
-
mimeType: "application/json",
|
|
1908
|
-
text: JSON.stringify(payload, null, 2)
|
|
1909
|
-
}
|
|
1910
|
-
]
|
|
1911
|
-
};
|
|
1912
|
-
}
|
|
1913
|
-
);
|
|
1914
|
-
}
|
|
1915
|
-
/**
|
|
1916
|
-
* Register audit backup tools for snapshot management.
|
|
1917
|
-
*/
|
|
1918
|
-
registerAuditBackupTools() {
|
|
1919
|
-
const backupManager = this.backupManager;
|
|
1920
|
-
if (!backupManager) return;
|
|
1921
|
-
this.server.registerTool(
|
|
1922
|
-
"sqlite_audit_list_backups",
|
|
1923
|
-
{
|
|
1924
|
-
title: "List Audit Backups",
|
|
1925
|
-
description: "List pre-mutation DDL snapshots captured before destructive operations. Returns metadata for each snapshot including timestamp, tool, target, and size.",
|
|
1926
|
-
annotations: {
|
|
1927
|
-
readOnlyHint: true,
|
|
1928
|
-
destructiveHint: false,
|
|
1929
|
-
idempotentHint: true,
|
|
1930
|
-
openWorldHint: false
|
|
1931
|
-
}
|
|
1932
|
-
},
|
|
1933
|
-
async () => {
|
|
1934
|
-
const snapshots = await backupManager.listSnapshots();
|
|
1935
|
-
return {
|
|
1936
|
-
content: [
|
|
1937
|
-
{
|
|
1938
|
-
type: "text",
|
|
1939
|
-
text: JSON.stringify(
|
|
1940
|
-
{
|
|
1941
|
-
snapshots,
|
|
1942
|
-
count: snapshots.length,
|
|
1943
|
-
_meta: {
|
|
1944
|
-
tokenEstimate: Math.ceil(
|
|
1945
|
-
Buffer.byteLength(JSON.stringify(snapshots), "utf8") / 4
|
|
1946
|
-
)
|
|
1947
|
-
}
|
|
1948
|
-
},
|
|
1949
|
-
null,
|
|
1950
|
-
2
|
|
1951
|
-
)
|
|
1952
|
-
}
|
|
1953
|
-
]
|
|
1954
|
-
};
|
|
1955
|
-
}
|
|
1956
|
-
);
|
|
1957
|
-
this.server.registerTool(
|
|
1958
|
-
"sqlite_audit_get_backup",
|
|
1959
|
-
{
|
|
1960
|
-
title: "Get Audit Backup",
|
|
1961
|
-
description: "Retrieve a specific pre-mutation DDL snapshot by filename. Returns the full snapshot content including DDL and optional data.",
|
|
1962
|
-
inputSchema: z.object({
|
|
1963
|
-
filename: z.string().describe(
|
|
1964
|
-
"Snapshot filename from sqlite_audit_list_backups results"
|
|
1965
|
-
)
|
|
1966
|
-
}),
|
|
1967
|
-
annotations: {
|
|
1968
|
-
readOnlyHint: true,
|
|
1969
|
-
destructiveHint: false,
|
|
1970
|
-
idempotentHint: true,
|
|
1971
|
-
openWorldHint: false
|
|
1972
|
-
}
|
|
1973
|
-
},
|
|
1974
|
-
async (args) => {
|
|
1975
|
-
const { filename } = args;
|
|
1976
|
-
const snapshot = await backupManager.getSnapshot(filename);
|
|
1977
|
-
if (!snapshot) {
|
|
1978
|
-
return {
|
|
1979
|
-
content: [
|
|
1980
|
-
{
|
|
1981
|
-
type: "text",
|
|
1982
|
-
text: JSON.stringify(
|
|
1983
|
-
{
|
|
1984
|
-
success: false,
|
|
1985
|
-
error: `Snapshot not found: ${filename}`
|
|
1986
|
-
},
|
|
1987
|
-
null,
|
|
1988
|
-
2
|
|
1989
|
-
)
|
|
1990
|
-
}
|
|
1991
|
-
],
|
|
1992
|
-
isError: true
|
|
1993
|
-
};
|
|
1994
|
-
}
|
|
1995
|
-
return {
|
|
1996
|
-
content: [
|
|
1997
|
-
{
|
|
1998
|
-
type: "text",
|
|
1999
|
-
text: JSON.stringify(snapshot, null, 2)
|
|
2000
|
-
}
|
|
2001
|
-
]
|
|
2002
|
-
};
|
|
2003
|
-
}
|
|
2004
|
-
);
|
|
2005
|
-
this.server.registerTool(
|
|
2006
|
-
"sqlite_audit_cleanup",
|
|
2007
|
-
{
|
|
2008
|
-
title: "Cleanup Audit Backups",
|
|
2009
|
-
description: "Apply retention policy to audit backup snapshots. Deletes snapshots exceeding age or count limits.",
|
|
2010
|
-
annotations: {
|
|
2011
|
-
readOnlyHint: false,
|
|
2012
|
-
destructiveHint: true,
|
|
2013
|
-
idempotentHint: true,
|
|
2014
|
-
openWorldHint: false
|
|
2015
|
-
}
|
|
2016
|
-
},
|
|
2017
|
-
async () => {
|
|
2018
|
-
const deleted = await backupManager.cleanup();
|
|
2019
|
-
return {
|
|
2020
|
-
content: [
|
|
2021
|
-
{
|
|
2022
|
-
type: "text",
|
|
2023
|
-
text: JSON.stringify(
|
|
2024
|
-
{
|
|
2025
|
-
success: true,
|
|
2026
|
-
deletedCount: deleted,
|
|
2027
|
-
message: deleted > 0 ? `Cleaned up ${String(deleted)} snapshot(s)` : "No snapshots to clean up"
|
|
2028
|
-
},
|
|
2029
|
-
null,
|
|
2030
|
-
2
|
|
2031
|
-
)
|
|
2032
|
-
}
|
|
2033
|
-
]
|
|
2034
|
-
};
|
|
2035
|
-
}
|
|
2036
|
-
);
|
|
2037
|
-
logger.info(
|
|
2038
|
-
"Registered audit backup tools: sqlite_audit_list_backups, sqlite_audit_get_backup, sqlite_audit_cleanup",
|
|
2039
|
-
{ module: "AUDIT" }
|
|
2040
|
-
);
|
|
2041
|
-
}
|
|
2042
2643
|
};
|
|
2043
2644
|
function createServer(config) {
|
|
2044
2645
|
return new DbMcpServer(config);
|