All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
5.0.1 - 2026-06-12
Dependency Updates
- Bumped
@types/nodefrom 25.9.1 to 25.9.3 - Bumped
typescript-eslintfrom 8.60.1 to 8.61.0 - Bumped
github/gh-aw-actionsfrom 0.64.2 to 0.79.7 - Bumped
pnpm/action-setuptofc06bc1257f339d1d5d8b3a19a8cae5388b55320
- Resolved Alpine OpenSSL CVEs (CVE-2026-34182, etc.) in Docker base image by fetching latest edge packages during build.
5.0.0 - 2026-06-06
- Contextual
README.mdfiles to core directories (.agents,.github,config,extensions,scripts,src,tests). TimeoutError,RateLimitError, andConflictErrortyped error classes.- WASM adapter request serialization via reader-writer lock.
stream: trueandchunkSizeparameters tosqlite_read_query.ALLOWED_IO_ROOTSsandbox via env var and CLI flag.- HTTP stateful session enforcement with 30-minute idle timeout and in-flight request locks.
- Optimistic Concurrency Control (OCC) tools in the
coregroup:sqlite_enable_versioning,sqlite_disable_versioning,sqlite_check_version, andsqlite_conditional_update. - Automatic
snake_casetocamelCaseparameter mapping in validation schemas and the Code Mode V8 proxy. - Test scripts
verify-schemas.mjs,test-zod-errors.mjs, andtest-tool-annotations.mjs. - Comprehensive vitest coverage suites for HTTP session initialization, system db, OAuth resource server, vector schemas, and SpatiaLite loader to achieve >90% overall project coverage.
- Deprecated
workerCode Mode isolation options in.env.example. - Updated default
CODE_MODE_MAX_RESULT_SIZElimit documentation to match 10MB runtime default. - Updated dependencies: GitHub Actions and npm packages.
- Clarified Code Mode testing rules in
prompt-template.mdand test scripts. - Surfaced Code Mode errors as structured typed errors instead of generic internals.
- Returned structured JSON for HTTP rate limit responses.
sqlite_write_queryandsqlite_upsertrequire anexpectedVersionparameter for version-enabled tables.- Bumped
isolated-vmto7.0.0for Node.js 26 compatibility. - Migrated package manager from
npmtopnpm(v9.15.4) and updatedDockerfile. - Simplified
gotchas.mdby moving tool-specific instructions to native tool group URIs. - Expanded agent prompts and E2E tests to validate
ALLOWED_IO_ROOTS, OCC, and chunked streaming. - Split complex tool handlers (
audit-tools.ts,window.ts) into sub-modules and grouped exports via barrel files. - Optimized error serialization overhead by extracting RegExp constants and adding match extraction caching.
- Optimized
ReadWriteLockfor WASM concurrency. - Accelerated Code Mode AST parsing with an LRU cache.
- Replaced generic
Errorclasses with domain-specific errors in core logic. - Updated server instructions (
gotchas.md) to formally document structuredValidationErrorresponses. - Added
(opt-in)annotation tosqlite.migrationin Code Mode groups list. - Optimized
sqlite_schema_snapshotto usecompact: trueby default. - Reduced
sqlite_stats_sampledefaultsampleSizeto 20 and max cap to 50. - Truncated
sqlite_transaction_executeresults array to a maximum of 50 items. - Changed
sqlite_dbstatdefaultsummarizetotrue. - Reduced
sqlite_audit_searchdefault limit to 10. - Converted
test-server/reset-database.ps1toreset-database.mjs. - Refactored
ErrorCategoryenum to a literal union type.
- Clean up orphaned SQLite Write-Ahead Log (
-wal) and Shared Memory (-shm) files during test environment resets. sqlite_read_querydegrades gracefully to full buffering in Code Mode whenstream: trueis requested.- Missing
PROJECT_REGISTRYandTEAM_DB_PATHvariables inmcp-config-example.jsonand.env.example. ci-health-monitorpermissions in strict mode.- Enforced single quotes in YAML frontmatter for agentic workflows.
- Enforced strict parsing (
.strict()) on empty schema objects in migration, admin, and transaction tools. - Typecast isolated
anytypes tounknownin admin schemas and metrics tests. - Refactored
logger.tsto be fully synchronous. - Removed unused
zod-to-json-schemadependency. - Code Mode sandbox timeouts now correctly throw
TimeoutError. - Native addon crashes during Vitest by changing the execution pool from
threadstoforks. - False-positive Promise rejections in
sqlite-adapter-methods.test.ts. - Synced
AUDIT_REDACTdefault totruein.env.exampleandmcp-config-example.json. - Configured
ALLOWED_IO_ROOTSin test scripts to automatically silence fallback sandbox warnings. - Generation script README exclusion now uses case-insensitive prefix matching.
- Removed unused devDependency
rimraffrompackage.json. - Structured error responses in vector tool handlers.
- Structured error responses in the
admin-audittool group. - Case-insensitive
operationparsing insqlite_cascade_simulator. - Coerce empty arrays in
sqlite_schema_diffschema. - Optional
tableparameter filtering insqlite_dependency_graph. - Descriptive messages in
json-writeoutput. findSuggestionregex pattern for missing column errors.- Strict validation in
transactionstool schemas. ifExistsdefault inDisableVersioningSchema.- Context extraction in
sqlite_fts_headlinewhencolumnis omitted. - Structured error category in
sqlite_analyze_csv_schemafor IO rejections. - Structured error fields in
sqlite_virtual_table_info. sqlite_audit_searchdocumentation parameter naming.
- Hard Gate: Code Mode strictly fail-closes if
isolated-vmnative bindings fail to load. - Hard Gate: HTTP transports fail to start if
ALLOWED_IO_ROOTSis omitted. - Stdio transport defaults to no filesystem access if omitted.
- Hardened all filesystem-touching tools to use symlink-aware realpath resolution (
assertSafeIoPath). - Sessions exceeding timeout limits are automatically expired and cleaned up.
4.0.0 - 2026-06-03
- CI/CD workflow documentation and Mermaid diagrams in
.github/workflows/README.md. Performance-Tuning.mdGitHub Wiki guide covering cache TTLs, WASM vs Native backends, and token efficiency.- Dependabot verification step in
.github/workflows/ci-health-monitor.md. - Internal server metrics exposed at
/metricsand viasqlite://metricsresource. sqlite_hybrid_searchtool combining FTS5 text search and vector embedding search via Reciprocal Rank Fusion (RRF).sqlite_audit_searchtool for querying server audit logs.sqlite_server_configadministrative tool to dynamically manage logging levels.includeFacetsandcursorparameters for faceted search and pagination in search/read queries.recommendCompositeandqueriesToAnalyzeoptions insqlite_index_auditfor automatic index recommendations.- SystemDb observability architecture with structured SQLite sidecar (
system.db) andMetricsRegistrypersistence. - Subscription capability via
SubscriptionManagerwithschemaChangedevents forsqlite://schemaandsqlite://tables. - Configuration file support (
.yaml,.json) via--configand--dump-configCLI flags. - Encryption at rest (SQLCipher) for Native backend and
SystemDblogs via--encryption-keyorDB_ENCRYPTION_KEY. - Capacity Planning Guide covering scaling, memory requirements, and token budgets.
- Continuous wiki documentation drift check workflow in
.github/workflows/wiki-drift-detector.md. - Data Privacy, Compliance policies, and Supply Chain Security guidance in
SECURITY.md.
- GitHub Actions workflows updated to use
actions/checkout@v6andactions/setup-node@v6via SHA pinning. sqlite_read_queryinstructions updated with token conservation guidance.- Dependencies bumped:
@vitest/coverage-v8to4.1.8,typescript-eslintto8.60.1, andvitestto4.1.8. - Agentic workflows updated to strictly use single quotes in YAML frontmatter and explicitly reference
gh copilot. mcp-config-example.jsonpopulated with meaningful placeholder values.
sqlite_append_insighttool andmemo://insightsresource.
MCP_HOSTdefault documentation discrepancy inREADME.mdandDOCKER_README.md(127.0.0.1locally,0.0.0.0in Docker).- Missing
MCP_ENABLE_HSTSvariable inDOCKER_README.mdEnvironment Variables table. - Silent fallbacks in
introspectionschemas swallowing wrong-type validation errors for enum properties. sqlite_spatialite_loadomittingversionstring required by the schema output.- Native build failure on Node 26 for Windows caused by LLVM/Clang LTO flags.
- FTS5 syntax errors on malformed user input.
- V8 Garbage Collection
STATUS_ACCESS_VIOLATIONcrashes duringCodeModeSandboxteardown. - Native V8 thread leaks on Windows.
- SQLCipher
PRAGMA keysyntax errors causing "file is not a database" failures. DB_ENCRYPTION_KEYenvironment variable leakage breaking unencrypted Playwright E2E tests.SubscriptionManagersilently dropping subscriptions over statelessstdiotransports.SchemaManager/describeTableomitting generated columns (resolved by cross-referencingtable_xinfoandsqlite_masterDDL).- Code Mode API normalization regression where parameter arrays were incorrectly processed in
searchRegex. - Missing AST validation error trigger in
sandbox.test.ts. - Automated subscription test scripts attempting DDL via
sqlite_write_queryinstead of dedicated DDL tools and using outdated SDK signatures. reset-database.ps1crashing withSQLITE_NOTADBduring encryption when database is locked (now gracefully warns).- Defunct
--auth-tokenargument remaining incli.tshelp text. SubscriptionManagerblindly broadcasting resource update notifications without verifying active subscribers for the URI.- Test output clarity and missing assertions in
test-subscriptions-raw.mjsandtest-subscriptions-sdk.mjs. - Test suite spawning failures with
SQLITE_NOTADBwhenDB_ENCRYPTION_KEYis present in the global environment. EXPECTED_TOOL_COUNTand missing administrative tools inSDK_REGISTERED_TOOLSintest-tool-annotations.mjs.- Refactored
test-progress.mjsto systematically iterate and rigorously verify all 7 progress-enabled tools instead of testing a single isolated loop.
- Bumped npm bundled
tarin Dockerfile to7.5.16to apply latest security patches.
3.0.2 - 2026-05-31
- Documentation: Created GitHub Wiki with 11 pages covering Quick Start, Tool Filtering, Code Mode, Tool Reference, HTTP Transport, SQLite Extensions, Resources & Prompts, OAuth & Security, Audit Trail, and Troubleshooting
- CI/CD: Added Docker smoke test jobs to
docker-publish.ymlandlint-and-test.ymlthat verify stdio, HTTP, and native SQLite backends start successfully on both amd64 and arm64 runners before images are pushed - CI/CD: Refactored
docker-publish.ymlfrom monolithic QEMU-emulated build to per-platform native runner matrix (ubuntu-24.04+ubuntu-24.04-arm), matching the fleet standard used bypostgres-mcpandmysql-mcp - Tests: Added
build-externals.test.tsinvariant test ensuring everytsup.config.tsexternal entry has a corresponding production dependency
- Docker: Fixed fatal startup crash in Docker image caused by missing
acorndependency (#149). The package was externalized in the build config but not listed independencies, causing it to be pruned from the productionnode_modules - Docker: Fixed ARM64
better-sqlite3native addon crash (Could not locate the bindings file) by switching from QEMU-emulated cross-compilation to native ARM64 runners. Added explicitnpm rebuild better-sqlite3in Dockerfile for defense-in-depth
3.0.1 - 2026-05-30
- Dependency Updates: Updated npm dependencies (e.g.
eslintto10.4.1). - Rewrote
test-server/scripts/test-tool-annotations.mjsfrom a basicopenWorldHintcounter into a comprehensive annotation validation suite. Now validates all 5 annotation fields (openWorldHint,readOnlyHint,destructiveHint,sensitiveHint,idempotentHint), checks logical consistency (e.g., noreadOnly+destructivecontradiction), enforces an exact allowlist foropenWorldHint=truetools, and validatestitlepresence.
- Fixed
sqlite_pragma_settingsannotation: removed incorrectopenWorldHint: trueoverride. PRAGMA operations are internal to the SQLite engine and don't interact with the filesystem or network. - Fixed a bug in
.github/workflows/codeql.ymlwhere CodeQL severity validation failed to block deployments. The SARIF parser now correctly inheritsdefaultConfiguration.levelwhen the finding level is omitted, and explicitly excludes thetests/directory from blocking production releases. - Fixed
tsconfig.test.jsonto properly include thetests/directory and addednpm run typecheck:teststo the main check script so CI catches test-related type errors. - Fixed "Invocation of non-function" CodeQL alerts in
utilities.bench.tsandtransport-auth.bench.tsby removing dead benchmark code referencing non-existent functions.
3.0.0 - 2026-05-29
- 20 new tools across Core, Admin, Stats, JSON, Introspection, and Server Audit groups.
sqlite.reportProgress()utility in Code Mode for sandboxed execution feedback.onlyDifferencesflag insqlite_json_difftool to filter identical rows.- Output schema registry and reference documentation for LLM invocations.
- Migrated Code Mode execution to native
isolated-vmfor V8 memory separation (withnode:vmfallback). - Bumped dependencies, including
@modelcontextprotocol/sdkto 1.29.0 andzodto 4.4.3. - Optimized token context-window usage via pagination, result truncation, wide-column validation, and computed date columns.
- Optimized
sqlite_text_replaceto skip rows without matches, saving DB I/O. - Enhanced DDL tools with support for
STRICTtables, generated columns, andsqlite_temp_master. - Improved Code Mode performance with LRU eviction and global WASM engine caching.
- Upgraded schema caching with a 30-second TTL and targeted DDL invalidation.
- Replaced
sqlite-parserwith an internal regex parser for structural validation. - Added MCP 2025 Specification annotations globally (
sensitiveHint,ASSISTANT_FOCUSED). - Filtered internal shadow tables from introspection resources.
- Migrated HTTP transport and Code Mode to support multi-instance Redis rate limiting.
- Standardized canonical names and tool inventory metrics across documentation.
- Clarified backend-switching documentation in READMEs.
- Simple Bearer Token authentication (replaced by strict OAuth 2.1).
- Redundant
test-wasm-degradation.mdprompt from the test suite.
- Fixed raw
-32602MCP errors by enforcing structured Zod validation across all tools. - Fixed numeric coercion falling back to
undefinedon invalid strings. - Restored
RETURNING *support in batch insert tools and fixed aliasing bugs in date functions. - Fixed Windows SpatiaLite loading by replacing
process.env.PATHmutations with a native C++ addon. - Fixed schema introspection failing to accurately map temporary table indexes.
- Fixed
sqlite_audit_restore_backupcrashing on comment-only snapshots. - Fixed false-positive path traversal violations on Windows caused by drive letter case sensitivity.
- Fixed WASM degradation test assertions for Code Mode.
- Fixed
sqlite_walfailing to enable WAL mode. - Fixed
sqlite_describe_tablefailing to accurately report thestrictproperty. - Fixed incorrect index assertion in Code Mode introspection queryPlan test prompt.
- Sandbox Isolation: Secured prototype freezing, disabled string code generation, and blocked constructor chain escapes.
- SQL Injection: Replaced template strings with native parameterized bindings and hardened WHERE clause generation.
- Authorization: Enforced explicit OAuth per-tool scopes and bound session IDs to authenticated subjects.
- Information Disclosure: Implemented recursive JSON redaction to sanitize credentials from outputs and logs.
- Transport: Bound HTTP server to
127.0.0.1, replaced insecure proxy headers, and mitigated timing attacks. - DoS: Upgraded rate limiters, capped Code Mode payloads to 50MB, and implemented 10KB query string bounds.
- Path Traversal: Blocked
:memory:, symlinks, and..sequence bypasses, and added filesystem boundary validations. - Supply Chain: Removed persistent credentials from workflows, enforced SHA pinning for actions, and verified lockfile integrity.
2.0.0 - 2026-05-21
-
Test Coverage: Added comprehensive test suites for anomaly detection (
sqlite_stats_detect_anomalies), bloat detection (sqlite_stats_detect_bloat), schema risk detection (sqlite_stats_detect_schema_risks), native extension loading (loadSpatialite,loadCsvExtension),BackupManagersnapshot generation/cleanup, FTS5 execution paths,WorkerSandboxAPI bindings and RPC functionality, resource error handling (sqlite_table_schema,sqlite_meta,sqlite_pragma,sqlite_compile_options), and adapter lifecycle fallback paths, reaching the 90.34% test coverage milestone. -
Progress Notifications: Added support for MCP long-running task progress notifications. Notifications are now correctly emitted during lengthy operations including
sqlite_backup(admin/backup),sqlite_migration_apply(migration/apply), andsqlite_virtual_analysis(virtual/analysis), ensuring cross-server parity with postgres-mcp and mysql-mcp. -
Initialization SQL: Added
initializationSql?: string[]toSqliteConfigfor SQLite connections, enabling per-connection session setup (e.g.PRAGMA foreign_keys = ON;). This executes exactly once when the adapter connects, satisfying the requirement for session-level guardrails across both Native (better-sqlite3) and WASM (sql.js) backends. -
Convenience Tools: Added 5 new tools to the
coregroup (sqlite_upsert,sqlite_batch_insert,sqlite_count,sqlite_exists,sqlite_truncate) to achieve complete feature parity withpostgres-mcp. These tools are available in both Native and WASM backends, withsqlite_upsertutilizing SQLite's nativeINSERT ON CONFLICT DO UPDATEorINSERT OR REPLACEfallback. -
sqlite_transaction_status: New read-only tool to check whether a SQLite transaction is currently active (native backend only). Returns{status: "active" | "none", active: boolean}. Ported frompg_transaction_statusfor cross-server parity. -
Audit Logging: JSONL audit trail with async-buffered writes, log rotation (10MB, 5-file cascade), and
sqlite://auditresource for agent access to the last 50 entries. Configurable via--audit-log <path>,--audit-redact,--audit-readsCLI flags orAUDIT_LOG,AUDIT_REDACT,AUDIT_READSenvironment variables. Write/admin tools are always logged; read tools optionally. -
DDL Backup Snapshots: Pre-mutation DDL capture for destructive operations (
sqlite_drop_table,sqlite_drop_index,sqlite_drop_view,sqlite_import_csv,sqlite_backup). Gzip-compressed snapshots with retention policy (age + count limits). Tools:sqlite_audit_list_backups,sqlite_audit_get_backup,sqlite_audit_cleanup. Enabled via--audit-backup/AUDIT_BACKUP. -
Token Burn-Rate: Every tool response now includes
_meta.tokenEstimate(~4 bytes/token heuristic). Code Mode responses includemetrics.tokenEstimate. Matches postgres-mcp and mysql-mcp for cross-server parity. -
Anomaly Detection Suite: 3 new stats tools for cross-server parity with postgres-mcp and mysql-mcp.
sqlite_stats_detect_anomalies(z-score data distribution analysis),sqlite_stats_detect_bloat(multi-factor fragmentation/bloat risk scoring via PRAGMA + dbstat),sqlite_stats_detect_schema_risks(schema health risk scoring — missing FK indexes, wide tables, missing PKs). All read-only, available in both WASM and Native backends, with Code Mode support viasqlite.stats.*. -
JSON Security Scan: New
sqlite_json_security_scantool for cross-server parity withpg_jsonb_security_scan. Scans JSON columns for sensitive keys (password, token, ssn, etc.), SQL injection patterns, and XSS attack vectors. ReturnsriskLevel(low/medium/high) and detailed issue breakdown. Uses JS-side regex scanning on sampled rows. Available in both WASM and Native backends. -
Text Sentiment: New
sqlite_text_sentimenttool for cross-server parity withpg_text_sentiment. Basic keyword-based sentiment analysis on raw text input. Returns sentiment classification (very_positive/positive/neutral/negative/very_negative), score, confidence, and optionally matched words. Pure JS implementation — available in both WASM and Native backends. -
FTS5 Headline: New
sqlite_fts_headlinetool for cross-server parity withpg_text_headline. Generates highlighted snippets from FTS5 search results using SQLite's nativehighlight()andsnippet()functions. Supports custom highlight markers and context window size. Native backend only. -
ExtensionNotAvailableError: New typed error class for extension unavailability (SpatiaLite, CSV, R-Tree). Code:EXTENSION_MISSING, category:config. Replaces ad-hoc inline error returns with a structured,instanceof-testable error. Ported from postgres-mcp for cross-server parity. -
Introspection Resources: Added
sqlite://compile_options(compile-time build features) andsqlite://pragma(runtime configuration snapshot) resources to achieve resource count parity withpostgres-mcp. Both are read-only and available unconditionally via theread_resourceMCP tool. -
WASM Mode Test Suite: Added
§7 WASM Mode Executionsection to the Code Mode test suite README with agent instructions for skipping[NATIVE ONLY]items, validating graceful degradation, and adjusting expectations for WASM-specific behavior (dbstat fallback, FTS3 vs FTS5, phantom FTS5 tables). -
WASM Degradation Prompt: New 11th test prompt (
test-tool-group-codemode-wasm-degradation.md) covering 10 categories of WASM-specific graceful degradation tests: API surface verification, backup/restore/verify errors, CSV/R-Tree unavailability, FTS5 phantom table behavior, dbstat fallback, PRAGMA compile options, and Zod validation of degraded tools. -
WASM Mode Advanced Tests: Added inline
## WASM Modesections to all 10 advanced stress test prompts (test-advanced/) with per-prompt skip rules, graceful degradation guidance, and adjusted expectations. Fixed admin Category 7 which incorrectly claimed all 26 admin tools work identically in WASM. -
WASM Mode Standard Tests: Added inline
## WASM Modesections to all 10 direct-tool test prompts (test-tool-groups/), replacing the staticIgnore WASM content. Test Native Mode Onlydirective. Each prompt now contains self-contained WASM skip rules with specific item numbers. Added§2.6 WASM Mode Executionsection to the README with skip rules, graceful degradation table, adjusted expectations, and the "unknown tool" note for unregistered Native-only tools.
-
Doc Parity Audit: Finalized repository documentation audit for v1.1.1. Synchronized all documentation across
README.md,DOCKER_README.md, andtest-resources.mdto reflect the current state of 151 Native / 125 WASM tools, 10 Tool Groups, and 20 Resources. -
Documentation Marketing Audit: Strengthened marketing copy in
README.mdandDOCKER_README.md. Promoted V8 isolate sandbox architecture in hero table Code Mode rows (previously described as generic "secure JavaScript sandbox"). Added_meta.tokenEstimatetoken burn-rate metric to Token-Optimized Payloads rows. Standardized token savings range to "70–90%" across both docs. Removed unsubstantiated "2 Minutes" Quick Start claim from Docker README. Fixed stray backslash in DOCKER_README env var table (OAUTH_AUDIENCErow). Fixed broken emoji (�→ 🔌) in README SQLite Extensions heading. Merged redundant Performance/Dual SQLite Backends hero table rows in README. -
Benchmark Ranges: Updated README benchmark summary from single-point estimates to 3-run ranges (e.g., "Tool dispatch: 11–14M ops/sec"). Added new "Sandbox execution" bullet (~4.4–4.9K exec/sec). Ranges reflect real-world variance from thermal throttling and background load.
-
Resource Payload Filtration Findings: Completed comprehensive testing of all 20 db-mcp resources (11 data + 9 help). Discovered that
sqlite_schema,sqlite_tables, andsqlite_viewsinclude internal Spatialite metadata tables/views (e.g.,geometry_columns,vector_layers). Recommendation: Filter out Spatialite internal objects similarly to FTS5 shadow tables to keep resource listings clean. All other resources (including schema templates, PRAGMA snapshots, Code Mode insights, and help files) and base tool annotations (openWorldHint: false) successfully passed validation. -
OAuth Identity in Audit Logs: Audit log entries now capture the authenticated user's identity (
userfield fromclaims.sub) and granted scopes (scopesarray) when OAuth 2.1 is configured. Previously hardcoded asnull/[]. Identity is read fromAsyncLocalStorageviagetAuthContext(), matching the postgres-mcp reference implementation. When OAuth is not configured (stdio transport, no auth), fields remainnull/[]as before. -
Zero-Suppression Architecture: Finalized the Zod Schema Registry by completely purging all inline
z.objectdefinitions and Zod imports from thesrc/adapters/sqlite/tools/directory. All schemas (includinggeo,fts,admin,json-operations, andvector) and their associated coercion utilities (coerceNumber,coerceUnit,coerceEnumValues) are now strictly centralized withinsrc/adapters/sqlite/schemas/, ensuring 100% modular decoupling and zero-suppression compliance. -
Documentation Parity: Updated all tool count references across
README.md,DOCKER_README.md,server.json,test-server/tool-reference.md, andtest-server/code-map.mdto reflect the expanded inventory (151 Native / 125 WASM tools), including the 5 new core convenience tools, JSON security scan, text sentiment, and FTS5 headline. -
Testing Prompts: Updated all 40 advanced and standard test prompts to default to the internal agent task tracking system instead of hardcoding a temporary local workspace file.
-
BREAKING: Transaction Group Split: Moved 8 transaction tools (
sqlite_transaction_begin,sqlite_transaction_status,sqlite_transaction_commit,sqlite_transaction_rollback,sqlite_transaction_savepoint,sqlite_transaction_release,sqlite_transaction_rollback_to,sqlite_transaction_execute) fromadmingroup into a dedicatedtransactionsgroup for improved discoverability. OAuth scope for transactions changed fromadmintowrite(matching mysql-mcp and postgres-mcp). Code Mode exposes transactions viasqlite.transactions.*namespace. -
BREAKING: Text Group Payload Optimization: Removed the redundant
originalstring field from the output schemas of 6 text tools (sqlite_text_case,sqlite_text_normalize,sqlite_text_split,sqlite_text_substring,sqlite_text_trim, andsqlite_text_sentiment). Tools now returnrowidfor traceability, immediately cutting JSON payload sizes by up to 50% for operations on large text columns. -
BREAKING: Vector Schema Parity: Standardized vector search and distance tool outputs (
sqlite.vector.searchnow returnsrows;sqlite.vector.distancenow returnsdistance) to align with cross-server canonical implementations (e.g.,postgres-mcp). -
BREAKING: Query Pagination Default: Lowered the default safety limit for unbounded SELECT queries from
1000to50to prevent unnecessary payload bloat and align with token-efficiency guidelines. -
BREAKING: Phonetic Payload Bloat: Changed
includeRowDatadefault inPhoneticMatchSchemafromtruetofalse. -
BREAKING: Migration Tools Hardening: Standardized the migration SQL payload property to
migrationSql(fromsql) across the SQLite handler code, Zod schemas, unit tests, and Playwright E2E tests, ensuring strict symmetry withrollbackSql. -
Updated
vitestand@vitest/coverage-v8to4.1.7. -
Updated
@types/nodeto 25.9.1,tsxto 4.22.3, andtypescript-eslintto 8.59.4. -
Updated
typescriptto^6.0.3,zodto^4.4.3,joseto^6.2.3,typescript-eslintto^8.59.3, and bumped various packages including@playwright/test,@types/node,@modelcontextprotocol/sdk,eslint,vitest,tsxto^4.22.1, andbetter-sqlite3. Updated Dockerfile overrides fordiff(9.0.0),tar(7.5.15), andminimatch(10.2.5). Updated GitHub Actions to their latest SHA-pinned versions (docker/build-push-action,actions/upload-artifact,docker/login-action,github/codeql-action,actions/cache,actions/setup-node).
- json-read: Fixed a Zod validation leak in
sqlite_json_querywherefilterPathswould throw a raw MCP-32602error if a client or LLM sent it as a stringified object instead of a record. - JSON Group Object Defaults: Fixed an issue in
sqlite_json_group_objectwherekeyColumnwas strictly required by Zod. It now correctly defaults to"rowid"when omitted, allowing queries to easily map values without specifying a key column. - JSON Read Numeric Coercion: Fixed a regression in
coerceNumberthat returned unparseable strings (like"abc") instead ofundefined. This ensures parameters likelimitandsampleSizecorrectly fall back to their defaults instead of throwing raw MCP-32602validation errors. - Anomaly Detection Column Parsing: Fixed an issue in
sqlite_stats_detect_anomalieswhere providing a singlecolumnargument was ignored, causing the tool to fall back to analyzing all numeric columns. Addedcolumnto theDetectAnomaliesSchemaand updated the tool handler to correctly prioritize single-column targets over the pluralcolumnsarray. - Resource Error Quality: Improved the error mapping logic in
query-executor.tsto intercept raw SQLite errors (Query execution failed: no such table/column) and translate them into strongly-typedResourceNotFoundErrorobjects. This elevates the error message quality from Level 3 (adequate) to Level 5 (excellent) by embedding the exact table/column name, appropriateTABLE_NOT_FOUND/COLUMN_NOT_FOUNDcodes, and actionable suggestions, completely replacing the raw SQLite fallback. - JSON Security Scan Parity: Fixed an issue in
sqlite_json_security_scanwhere the ported SQL injection pattern did not detect' OR 1=1variants and command/template injection patterns (${cmd}) were missing entirely. Added a newcmd_injection_patternto the Zod schema and expanded regex matching. - Code Mode Undefined Serialization: Fixed an issue where returning
undefinedfrom the sandbox resulted in a serialized error object ({"_error":"Result could not be serialized","_type":"undefined"}) rather than properly handling it as an empty result.sanitizeResultnow explicitly handlesundefinedwhile preserving the serialization catch for unsupported types like functions or symbols. - E2E Transport Timeouts: Resolved intermittent 60-second timeouts (
TypeError: Expected a ServerResponse) in the WASM Playwright E2E suite by introducing aconnectionMutexinsession.tsto strictly serializeMcpServerconnection handoffs and synchronously clean up legacyProtocol._transportstates. - Reset Script: Fixed a PowerShell here-string syntax error (
ParseExceptiondue to missing terminator) intest-server/reset-database.ps1that prevented the test database from being reset. - Fixed OAuth scope enforcement gap where tools were missing authorization level verification at the HTTP transport layer before being dispatched to the MCP handler.
- Code Mode last-expression auto-return — Bare expressions like
sqlite.help()now correctly surface their return value fromsqlite_execute_code. Previously, the async IIFE wrapper silently returnedundefinedfor non-returnstatements. NewtransformAutoReturn()utility prependsreturnto the last expression statement, mimicking Node REPL semantics. Applied to both VM and Worker sandbox paths. - Structured Error Parity — Fixed an issue in
sqlite_generate_seriesandsqlite_create_series_tablewhere validation errors for missing parameters (due to SDK compatibility constraints) bypassed Zod and returned ad-hoc objects missingcode(VALIDATION_ERROR) andcategoryfields. - Schema Strict Validation Leak — Fixed an issue in
sqlite_countandsqlite_existswhereZodSchemadefinitions lacked.strict()and caused unknown parameters (e.g., typos likewhereClauseinstead ofwhere) to be silently ignored, executing broad queries instead of rejecting the input. AliasedwhereClausecorrectly towhereinconvenience-schemas. - Code Mode Discovery parity —
sqlite.help()within Code Mode worker processes now properly computes and returnstotalMethodsandusageinstructions to match the top-level API shape. - Audit Logging Silent Failure — Fixed a bug where audit logs were not writing to the configured JSONL file despite being enabled. Tool names in
toolScopeMapwere missing theirsqlite_prefix (e.g.,"execute_code"instead of"sqlite_execute_code"), causing them to fall back to thereadscope and skip logging when--audit-readswas false. Added correct prefixing during scope map initialization and fixedtypescript-eslinttyping strictness issues (no-unsafe-call,strict-boolean-expressions) in the audit interceptor. - Migration Tools Hardening — Standardized the migration SQL payload property to
migrationSql(fromsql) across the SQLite handler code, Zod schemas, unit tests, and Playwright E2E tests, ensuring strict symmetry withrollbackSqland resolving validation discrepancies. - Admin Code Mode Prompt: Fixed a syntax error in the admin code mode test prompt (
test-tool-group-codemode-admin.md) wheresqlite.core.describeTable("...")was incorrectly used instead of the object-parameter syntaxsqlite.core.describeTable({table: "..."}). - Automated Coverage & E2E Badges — Ported
update-badges.tsscript to automatically update theREADME.mdandDOCKER_README.mdcoverage and E2E statistics. Updatedvitest.config.tsandplaywright.config.tsto outputjson-summaryandjsonresults respectively, and hooked the badge updater into thetest:coverageandtest:e2enpm scripts. - Code Mode Text Tests — Fixed a documentation discrepancy in
server-instructions/text.mdwheresqlite_text_replacewas documented withsearch/replacementinstead ofsearchPattern/replaceWith. - Code Mode Transactions Tests — Remediated syntax discrepancies in the transactions tool group testing prompt where the test template incorrectly used
sqlite.transactions.transactionStatus()instead ofsqlite.transactions.status(). - Testing Prompts: Reverted
test-tool-group-codemode-vector.mdand E2E tests to enforce strict output schemas (rowsinstead ofresults,distanceinstead ofvalue) under the Code-Over-Docs policy. - Gotchas Documentation: Removed vector schema discrepancy caveats from
gotchas.mdnow that the canonical outputs are enforced. - Core Group Stress Testing: Fixed schema aliases in
CountSchemaandBasicStatsSchemato properly accepttableNameandcolumnNameinputs, standardizing parameter names across thecoreandstatstool groups and resolving validation errors encountered during Code Mode execution. - Sentiment Tool Parity: Refactored the
sqlite.text.sentimenthandler and associated schemas to process a pure JStextstring rather than executing database queries, resolving schema mismatch errors and aligning the SQLite implementation with thepostgres-mcpparity standard. - Sentiment Tool Types & Linting: Resolved TypeScript (
no-explicit-any) and ESLint (require-await) errors within the sentiment tool by typing the output with a strictSentimentResultinterface and correctly handling async handler requirements. - Text Group Test Suite: Rewrote
tests/adapters/sqlite/tools/text/sentiment.test.tsto pass literal strings and evaluate the new direct object payload, allowing 100% test coverage to pass cleanly. - RowID Aliasing Bug: Fixed an issue in
sqlite_text_normalize,sqlite_text_validate, andsqlite_text_sentimentwhere therowidproperty was missing or returned0for tables withINTEGER PRIMARY KEY. Properly aliasedrowid as idin the read queries to ensure consistent row identification. - RowID Aliasing Bug (Part 2): Extended the rowid aliasing fix (
SELECT rowid as __rowid) tosqlite_text_trim,sqlite_text_case, andsqlite_text_substringtools to ensure consistent row identification across the entire text group, preventingbetter-sqlite3from overriding therowidalias with the primary key name. - FTS Create Schema Alias: Updated
FtsCreateSchemaand the handler logic insqlite_fts_createto acceptftsTableas an alias fortableName, resolving parameter discrepancies during tool group testing while adhering to the "Code Over Docs" policy. - Bloat Payload Scaling: Fixed an issue in
sqlite_stats_detect_bloatandsqlite_stats_detect_schema_riskswhere the tools returned the entire table list unconditionally. Added anincludeZeroRiskparameter (default: false) to filter out zero-risk tables, reducing thedetect_schema_riskspayload by >70% on healthy databases. - WASM Code Mode Capability Filtering: Fixed a bug where
sqlite.help()within Code Mode exposed empty namespaces (liketransactions) or incorrectly filtered out the 4 basic geo tools (distance, nearby, bounding box, cluster) on the WASM backend. UpdatedSqliteAdapter.getAvailableToolDefinitions()to strictly filter out only SpatiaLite tools and FTS5 tools, correctly reporting 9 accessible groups in WASM. - Introspection Graph Row Counts: Fixed a bug where
sqlite_dependency_graphhardcodedrowCountto0by default. ModifiedbuildForeignKeyGraphto explicitly query actual row counts whenincludeRowCountsis true. This also resolves an issue wheresqlite_cascade_simulatorerroneously reportedestimatedRows: 0for all cascaded table actions. - Introspection Payload Bloat: Fixed an issue where
sqlite_schema_snapshotandsqlite_dependency_graphincluded all FTS5 shadow tables (e.g.,*_fts_data,*_fts_idx), unnecessarily bloating payload sizes. FTS shadow tables are now explicitly filtered out from tables, views, indexes, and triggers arrays. - Resource Templating Error Pattern: Fixed an issue where the
sqlite_table_schemaresource threw an unhandled framework exception when requesting the schema for a nonexistent table. Wrapped theadapter.describeTable()call in atry/catchto cleanly return a structured JSON error response ({"success": false, "error": "Table '...' does not exist"}). - Help Resource Registration Leak: Fixed a registration gap where group-specific help resources (e.g.
sqlite://help/admin) were not properly exposed when thecodemodetool filter was uniquely enabled. Refined the explicit check inmcp-server.tstothis.toolFilter.enabledGroups.size === 1 && this.toolFilter.enabledGroups.has("codemode"), ensuring sandbox agents retain full access to internal group documentation without accidentally leaking help files to restricted filter profiles. - Test Documentation Alignment: Updated
test-server/test-resources.mdto align with the canonicalsqlite_append_insighttool schema, changing the documented manual test payload from{ category, finding }to the actually implemented{ insight: "..." }. - Pragma Settings Exception Leak: Fixed an issue in
sqlite_pragma_settingswhere writing to pragmas that do not return data (e.g.,cache_size) threw an internal "does not return data"better-sqlite3exception. The error was incorrectly caught and returned as aVALIDATION_ERROR. The handler now properly delegates PRAGMA writes toexecuteWriteQuery, ensuring successful writes complete without errors and no validation payload is incorrectly emitted. - Migration Rollback Validation: Fixed an issue in
MigrationRollbackValidationSchemawhere an empty input{}bypassed Zod validation and triggered a downstream domain error. Added a requirement check in thesuperRefineblock to enforce that eitheridorversionmust be provided, ensuring aVALIDATION_ERRORis correctly thrown before domain execution. - Code Mode Timeout Enforcement: Fixed an issue where the
timeoutparameter insqlite_execute_codeenforced a minimum of1000ms, despite allowing configurations down to500ms. Updated both the Zod schema (ExecuteCodeSchema) and the handler-level guard incodemode.tsto correctly allow timeouts down to500ms. - Gotchas Documentation: Removed the obsolete FTS5 rebuild requirement (Gotcha #5) from
gotchas.mdsincesqlite_fts_createautomatically populates the index upon creation. - Read Query Validator Context: Fixed an issue where the
sqlite_read_queryandsqlite_write_queryvalidators blocked invalid statements (e.g., misspelled keywords) with a genericVALIDATION_ERRORbut provided no SQL context. Added the original query string to the errordetails.sqlto satisfy "structured error with SQL syntax context" testing requirements. - Code Mode Silent Failures: Fixed an issue in the Code Mode Sandbox (
sqlite_execute_code) where tool handlers that encountered validation errors or query failures silently returned an object{ success: false, error: ... }instead of throwing a JavaScript exception. The API wrapper insrc/codemode/api.tsnow inspects handler results and explicitly throws anErroron failure, ensuring scripts fail fast natively and errors bubble up correctly without requiring explicitif (!res.success)checks. - Code Mode RPC Error Masking: Fixed an issue in
sqlite_execute_codewhere validation errors for tools returning amessage: ""property inadvertently overwrote the internalerr.messageduring Sandbox proxy mapping, causing silentundefinedresolutions. Additionally, upgraded theWorkerSandboxRPC payload (RpcResponse) to extract and transmit custom Error properties (e.g.,code,category,sql), ensuring that structured errors correctly traverse theworker_threadsboundary into the user's sandbox code. - Code Mode Error Throw Reversion: Reverted a previous change in
src/codemode/api.tsthat caused Code Mode to throw JS exceptions on domain/validation errors. To comply with the Structured Error standard, Code Mode API now correctly returns the{ success: false, error: ... }object directly rather than throwing, allowing scripts to inspect errors natively withouttry/catchand preventing raw MCP errors from unhandled exceptions. - Migration Record Validation: Fixed an issue in
MigrationRecordValidationSchemawhere passing an empty object{}bypassed the requirement for SQL content. Added a.superRefinecheck to enforce that eithersqlormigrationSqlmust be provided, ensuring aVALIDATION_ERRORis correctly thrown before domain execution. - Stats Error Standardization: Refactored the
statstool group to strictly throwValidationErrorandResourceNotFoundErrorexceptions instead of returning manual ad-hoc error objects. UpdatedstatsHistogram,statsPercentile,statsCorrelation,statsDetectAnomalies, and thevalidateNumericColumnhelper, ensuring complete parity with the project's Structured Error formats and allowingformatHandlerErrorto properly intercept and format the outputs. - Nested Transaction Execution: Fixed an issue in
sqlite_transaction_executewhere executing multiple statements inside an already-active manual transaction failed withTRANSACTION_CONFLICT. The tool now detects active transactions, skips the redundantBEGIN/COMMIT, executes the statements seamlessly within the parent transaction context, and correctly triggers a full rollback if any statement fails androllbackOnErroris enabled, eliminating lingering aborted states. - Transaction Failed To Start Logic: Fixed an issue in
sqlite_transaction_executewhere rolling back a pre-existing transaction during a failure inside.execute()incorrectly output the error message"Transaction failed to start"instead of"Transaction rolled back". Correctedtransactions.tsby ensuring!originallyInTransactioncheck logic evaluates before overridingrollbackMessage. - Core Convenience Schema Return Values: Fixed an issue where
sqlite_upsertandsqlite_batch_inserttriggered raw MCP validation errors when passedreturning: trueas a boolean. Updated schemas to accept boolean OR array of strings, and improved handler to supportRETURNING *. - Core Write Query Output Schema Parity: Fixed an issue where the
WriteQueryOutputSchemalacked therowsproperty. It now explicitly declaresrows: z.array(RowRecordSchema).optional()to ensure returned rows from INSERT/UPDATE... RETURNING statements are correctly validated by the SDK and not rejected as unexpected additional properties. - Core Write Query Return Rows: Fixed an issue in
query-executor.ts(WASM) andnative-query-executor.ts(Native) whereexecuteWriteQueryfailed to actually return the rows affected byRETURNINGclauses because they defaulted todb.run()instead of.exec()or.all(). Handlers now correctly inspect the query or statement reader and extract the inserted/updated rows. - Core Data Test Prompt Fix: Identified that the test prompt erroneously expected
CREATE TABLEandDROP TABLEto succeed viasqlite_write_query, despite explicit architectural enforcement rejecting DDL commands in favor ofsqlite_create_table/sqlite_drop_table. Handlers correctly rejected these; no code changes were made to DDL constraints, but the test expectations were noted as factually incorrect. - Storage Analysis Limit Leak: Fixed an issue in
StorageAnalysisSchemawhere the.min(1)and.max(500)Zod refinements on thelimitparameter bypassed the try/catch handler and leaked as raw MCP framework errors. The refinements were removed from the schema and boundary validation logic was moved inside thesqlite_storage_analysishandler usingValidationErrorto guarantee strict structured{success: false, error: ..., code: "VALIDATION_ERROR"}responses. - SpatiaLite GeoJSON Validation: Fixed an issue in
sqlite_spatialite_importwhere invalid GeoJSON input (such as a FeatureCollection) silently resulted in aNULLgeometry insertion because the SQLiteGeomFromGeoJSONfunction quietly returns null for invalid formats. Added a pre-validation query to ensure the parsed geometry is strictly valid before executing theINSERT, matching the existing WKT validation pipeline. - SpatiaLite Index Verification: Fixed an issue in
sqlite_spatialite_indexwhere checking for the existence of an index incorrectly queriedsqlite_masterfor virtual tables, resulting in false negatives andnullchecks on SpatiaLite 5.x. TheindexExistshelper now queries thegeometry_columnstable (spatial_index_enabledflag) to accurately reflect index state. Additionally, added strict return value verification (=== 0) toCreateSpatialIndexandDisableSpatialIndexexecutions to prevent silent failures when generating or dropping the R-Tree tables. - JSON Error Standardization: Refactored the
jsontool group to strictly throwValidationErrorexceptions instead of returning manual ad-hoc error objects. Updated tools acrosscrud.tsandwrite.ts(e.g.,sqlite_json_extract,sqlite_json_set,sqlite_json_insert,sqlite_json_update), ensuring complete parity with the project's Structured Error formats and allowingformatHandlerErrorto properly intercept and format the outputs for invalid JSON paths and missing required parameters. - Zod Schema Numeric Validation Leak: Fixed a major framework-level validation bypass where passing invalid string inputs to
.optional().default(x)numeric properties (e.g.,buckets: "four") resulted in a raw MCP SDK error (-32602 Input validation error: expected number, received string) rather than a structured internal error. This occurred becausecoerceNumberreturned the invalid string directly to the schema instead of returningundefined. UpdatedcoerceNumberacross all 10 schema files (stats.ts,geo.ts,window.ts, etc.) to returnundefinedforisNaNinputs, ensuring Zod gracefully falls back to default values or emits proper handler-levelVALIDATION_ERRORresponses. - Introspection Tools Schema Parity: Fixed an issue where
sqlite_get_indexeswould not correctly accept thetableNamealias from MCP clients becauseGetIndexesSchemalacked the alias definition, causing it to be stripped during strict SDK validation. - E2E Test DB State Corruption: Fixed E2E test suite cascading failures (
test_ordersrow checks, constraint/cascade simulators, and prompt schema reads) caused by corrupted test database state left over from isolated Code Mode testing sessions. Resettest.dbto its canonical seed state. - Code Mode Schema Mismatch: Added missing
tokenEstimatefield toExecuteCodeOutputSchemametrics object to prevent silent output schema omissions and correctly validatemetrics.tokenEstimatein Code Mode execution results.
- CI/CD Hardening: Added
--provenanceflag tonpm publishinpublish-npm.ymlfor SLSA Build L3 attestation. Addedid-token: writepermission for OIDC provenance token generation. - CI/CD Harmonization:
- Added
secrets-scanning.yml(TruffleHog + Gitleaks on every push/PR) - Added
dependabot-auto-merge.yml(auto-squash patch/minor, manual review for major) - Added Trivy container scan + SARIF upload to
docker-publish.ymlsecurity-scan job - Added
.gitleaks.tomland.trivyignoreconfiguration files
- Added
- Vulnerability Remediation: Resolved Vite, Hono, path-to-regexp, fast-uri, Picomatch, and ip-address vulnerabilities via
npm updateand transitive lockfile resolutions. - Docker Image Hardening: Pinned Alpine edge packages (
openssl,musl,nghttp2) and manually updated npm's bundledbrace-expansionto resolve multiple Docker Scout CVEs.
1.1.1 - 2026-03-18
- Version Management: Both SQLite adapters now import
VERSIONfromsrc/version.ts— onlypackage.jsonneeds updating on version bumps - Version Test: Derive expected adapter version from
VERSIONconstant instead of hardcoded string
- Docker Build: Adjusted Docker/CI build configuration so
tsupreceives the correct inputs, fixing "No input files" CI build failure - Docker Workflow: Updated all
docker/setup-buildx-actionrefs from v3 (Node 20, deprecated) to v4 (Node 24) - Docker Workflow: Fixed
peter-evans/dockerhub-descriptionbroken SHA — updated to v5 release (1b9a80c) - Prompt Handler: Made
argsoptional inhandleResultto prevent crash when SDK invokes prompts withundefinedargs - Transaction Methods: Replaced generic
ErrorwithValidationError+INVALID_SAVEPOINT_NAMEcode for savepoint name validation - Index Tools: Centralized table existence checks via
validateTableExists()fromcolumn-validation.ts
1.1.0 - 2026-03-18
- E2E Tests: Ported 32 HTTP transport e2e tests from memory-journal-mcp covering streaming (raw SSE for GET /mcp and GET /sse), advanced session management (cross-protocol guard, sequential isolation, post-DELETE rejection), rate limiting (429 burst, Retry-After header, health exemption), and OAuth 2.1 discovery (RFC 9728 metadata, scopes, auth gating). Enriched existing health and security specs with timestamp validation, session ID checks, CORS header assertions, and HSTS opt-in testing. Added
startServer()/stopServer()managed child-process lifecycle helpers. - Integration Test Scripts: Ported
test-instruction-levels.mjsandtest-tool-annotations.mjsterminal scripts from memory-journal-mcp totest-server/. - MCP Compliance: Added
READ_ONLYannotations (openWorldHint: false) to 3 built-in server tools (server_info,server_health,list_adapters). Added missingopenWorldHint: falsetosqlite_execute_codecodemode tool. All 118+ tools now have complete MCP annotations. - Help Resources: Added
sqlite://helpandsqlite://help/{group}MCP resources for on-demand tool reference documentation. Agents receive a slim ~680-charinstructionspayload pointing to these resources, instead of the previous ~3.5K+ payload that exceeded MCP client character limits and was silently truncated. Help resources are filtered by--tool-filter— only enabled groups get help resources registered. - Help Resources: Added
sqlite://help/introspectionandsqlite://help/migrationhelp resources — these tool groups were missing dedicated help content, leaving HTTP/SSE/streaming users without access to reference documentation for 15 tools. - E2E Tests: Added 6 new spec files (~209 tests) automating the deterministic portions of manual agent testing prompts:
zod-sweep.spec.ts(Zod validation sweep — every tool with required params called with{}),errors-extended.spec.ts(per-group domain error paths),codemode.spec.ts(sandbox lifecycle, security, readonly, workflows),codemode-groups.spec.ts(all 9 groups viasqlite.*API),numeric-coercion.spec.ts(string-typed numeric params),boundary.spec.ts(empty tables, NULLs, idempotency, edge cases). AddedexpectHandlerErrorandcallToolRawhelpers tohelpers.ts. - E2E Tests: Added 3 native-only spec files expanding systematic validation coverage to native-exclusive tools:
zod-sweep-native.spec.ts(20 tools — FTS5, window functions, transactions, SpatiaLite called with{}),errors-native.spec.ts(20 error path tests — nonexistent tables/columns, invalid SQL/WKT, bad savepoints),numeric-coercion-native.spec.ts(8 tests — string-typed numeric params for windowwindowSize/buckets/offset/limit, FTSlimit, transactionmode). Raises Zod sweep coverage from 83% to 98% of all tools. - E2E Tests: Added
help-resources.spec.ts(11 tests — validatessqlite://helproot + all 8 group help resources are listed, readable, and return non-empty markdown) andaliases.spec.ts(14 tests — validates backward-compatible parameter aliasestableName→table,sql→query,name→indexNameacross all 8 core tools including precedence and error paths). - Annotation Invariant Tests: Added
tool-annotations.test.tsthat enforces every tool in both WASM and Native adapters hasannotationswith explicitreadOnlyHint. Includes per-group checks (all stats/introspection tools must bereadOnly), specific window function assertions, and title validation. Would have caught the 6 missing window function annotations and the 7 missing transaction annotations. - Output Schema Invariant Tests: Added
tool-output-schemas.test.tsthat enforces every tool has anoutputSchemadefined, every schema is a valid Zod schema, every schema accepts error responses ({success: false, error: "..."}), schemas reference centralizedoutput-schemas/exports (not inlinez.object()), specific tool-to-schema wiring for ~70 tools, and no orphan schemas exist. Covers both WASM and Native adapters. - E2E Tests: Added 6 window function readonly smoke tests to
codemode.spec.ts— verifies all window tools (windowRowNumber,windowRank,windowLagLead,windowRunningTotal,windowMovingAvg,windowNtile) work inreadonly: truemode on native and are correctly unavailable on WASM. Uses dual-branch assertions (zero skips). - Window Tool Tests: Added annotation assertions to
ranking.test.ts— verifies all 6 window tools havereadOnlyannotations with titles. - E2E Tests (Prompt Audit): Added 12 gap-closing tests identified by auditing manual testing prompts against automated suites: (1)
codemode.spec.ts— API discoverability tests forsqlite.help(), per-grouphelp(), method aliases, convenience aliases, and all 9 groups returning>0methods; timeout enforcement for infinite loops. (2)payloads-stats-advanced.spec.ts— self-correlation edge case (column1 === column2 → ≈1.0). (3)payloads-fts.spec.ts— FTS5 boolean AND/NOT operators. (4)payloads-migration.spec.ts— duplicate version string rejection. (5)boundary.spec.ts— vector empty table edge cases (count, search, stats, dimensions on table with 0 vectors). (6) Newcodemode-introspection.spec.ts(~16 tests) — introspection code-mode-only params (sections,compact,checks,table,includeTableDetails,limit,direction). (7) Newtransactions-nested.spec.ts(~4 tests) — nested savepoint data correctness (rollback_to sp2 keeps sp1 data; rollback_to sp1 undoes everything after sp1). (8) Newintegration-workflows.spec.ts(~8 tests) — cross-group pipelines (Core→JSON→Stats, Core→Vector→Text, Admin→Introspection health check, Core+Stats cross-validation, data integrity verification). - E2E Tests (Resource + Prompt Depth): Added 13 gap-closing tests by auditing
test-resources.mdandtest-prompts.mdagainst existing specs. Resources (R1–R9): schema table count + names, templated reads (sqlite://table/test_products/schema+test_orders), nonexistent table error, index name assertions (idx_orders_status,idx_products_category), health backend info, meta PRAGMA fields (page_size), views empty array, insights write+read cycle viasqlite_append_insight, help keyword assertions ("gotcha", "code mode", "wasm"). Prompts (P1–P4): data-fetching prompts embed real table names (explain_schemacontains "test_products"), argsSchema on prompts with required args (query_builder ≥3, data_analysis ≥1, explain_schema 0), missing required args graceful handling, deeper content assertions (debug_query reflects submitted SQL, migration reflects change description). - Error Handling —
TransactionErrorSubclass — NewTransactionErrorclass inutils/errors/classes.tsfor commit/rollback/savepoint failures, usingQUERYcategory withrecoverable: true - Error Handling —
ErrorContextInterface — NewErrorContextinterface inutils/errors/format.tsfor optional tool/table/sql context on error formatting calls - Error Handling —
formatHandlerErrorExport — Canonical cross-project name for the primary error formatter;formatErrorremains as an alias - Error Handling — Zod Path Extraction —
formatHandlerErrornow extracts field paths from ZodErrors (e.g.,table: Requiredinstead of raw JSON issue arrays) - OAuth —
FULLScope — Addedfullscope that grants unrestricted access to all operations, completing thefull ⊃ admin ⊃ write ⊃ readhierarchy - OAuth —
TOOL_GROUP_SCOPESMapping — DeclarativeRecord<ToolGroup, StandardScope>replaces imperative*_SCOPE_GROUPSarrays as single source of truth - OAuth — Scope Utilities — Added
hasScope(),hasAnyScope(),hasAllScopes(),getScopeForToolGroup(),getScopeDisplayName()for hierarchical scope checks - OAuth — Scope Map — New
scope-map.tswithgetRequiredScope()for O(1) tool-name-to-scope reverse lookup - OAuth — Auth Context — New
auth-context.tsusingAsyncLocalStoragefor per-request auth context threading to tool handlers - OAuth — Transport-Agnostic Auth — Added
AuthenticatedContext,createAuthenticatedContext(),validateAuth(),formatOAuthError()to decouple auth from Express - OAuth — Resource Server Enhancements — Added
isScopeSupported(),getWellKnownPath(),resource_documentation,resource_signing_alg_values_supportedto RFC 9728 metadata - OAuth — Unit Test Coverage — Added 8 unit test files for complete auth module coverage: scopes, scope-map, auth-context, errors, oauth-resource-server, middleware, token-validator, authorization-server-discovery
- Transport Feature Backport —
trustProxyconfig option for X-Forwarded-For client IP extraction behind reverse proxies - Transport Feature Backport —
enableHSTS/hstsMaxAgeconfig options (HSTS now opt-in, was always-on) - Transport Feature Backport — Wildcard subdomain CORS matching (e.g.,
*.example.com) - Transport Feature Backport — New
middleware.test.tswith 14 unit tests forgetClientIp()andmatchesCorsOrigin() - Playwright E2E Test Suite — 12 spec files, dual-adapter (WASM + Native) and dual-transport (SSE + Streamable HTTP) coverage
health.spec.ts: Health endpoint and MCP initialization handshakeprotocols.spec.ts: Streamable HTTP and Legacy SSE protocol validation (session IDs, invalid JSON, missing params)tools.spec.ts: Tool listing, read/write execution, validation errors, Code Mode, and cross-group coverage (all 9 tool groups) via MCP SDK Clientsecurity.spec.ts: 404 handler, 413 payload limit, security headers, CORS preflight, OAuth status, Referrer-Policysessions.spec.ts: Full Streamable HTTP session lifecycle — init, notifications, tool calls with session ID, SSE/DELETE rejection, terminationstateless.spec.ts: Stateless mode (--stateless) — session-free POST, SSE 405, DELETE no-op, legacy SSE 404, healthresources.spec.ts: All 7 static MCP resources (sqlite://schema,tables,health,indexes,views,meta,memo://insights) and resource templates via SDK Clientprompts.spec.ts: List + get all 10 MCP prompts with representative argumentsstreamable-http.spec.ts: Streamable HTTP transport (MCP 2025-03-26) — init, tools, resources, prompts via modern transportnative.spec.ts: Native-only tools — transactions (begin/rollback), FTS5 search, window functions (row_number)wasm.spec.ts: WASM graceful degradation — transactions rejected, backup/restore/verify returnwasmLimitationerrors.spec.ts: Structured error response contract — TABLE_NOT_FOUND, COLUMN_NOT_FOUND, statement type mismatches, coordinate validation, non-numeric column detection- Dual-project
playwright.config.ts: WASM adapter (port 3000) + Native adapter (port 3001) with--tool-filter +all test:e2enpm script, dedicatede2e.ymlCI workflow, E2E badge added to README
- Performance Benchmark Suite — 9 benchmark files measuring framework overhead on critical hot paths
handler-dispatch.bench.ts: Tool lookup, error construction, progress notification overheadutilities.bench.ts: Identifier sanitization, WHERE clause validation, SQL validation, metadata cachingtool-filtering.bench.ts: Filter parsing, group lookups, meta-group catalog generationschema-parsing.bench.ts: Zod schema validation for simple/complex/large payloads and failure pathslogger-sanitization.bench.ts: Log call overhead, message sanitization, stack trace processing, sensitive data redactiontransport-auth.bench.ts: Token extraction, scope checking, error formatting, rate limitingcodemode.bench.ts: Sandbox creation/disposal, pool lifecycle, security validation, execution overheaddatabase-operations.bench.ts: PRAGMA operations, table metadata, query result processing, JSON path validation, schema cachingresource-prompts.bench.ts: Resource URI matching, content assembly, prompt generation, tool index generationnpm run benchandnpm run bench:verbosescripts;vitest.config.tsbenchmark configuration
- Introspection Tool Group (6 tools) — Read-only schema analysis and dependency mapping
sqlite_dependency_graph: Build directed FK dependency graphs with depth/direction controlsqlite_topological_sort: Determine safe creation/drop order for tablessqlite_cascade_simulator: Preview cascade effects before running DELETE/DROPsqlite_schema_snapshot: Capture full or partial schema with SHA-256 fingerprintingsqlite_constraint_analysis: Analyze FK constraints, detect orphans, unindexed FKssqlite_migration_risks: Assess risk levels for DDL migration statements- All tools are strictly read-only (no database modifications)
- Migration Tool Group (6 tools) — Opt-in schema migration lifecycle management
sqlite_migration_init: Create_mcp_migrationstracking tablesqlite_migration_record: Record a migration without executing (audit/tracking)sqlite_migration_apply: Execute + record migration atomically with rollback SQLsqlite_migration_rollback: Reverse a migration using stored rollback SQLsqlite_migration_history: Query migration history with status/version filterssqlite_migration_status: Dashboard summary of migration state- SHA-256 deduplication prevents accidental re-application
- All tools require
writeoradminscope
dev-schemaMeta-Group Shortcut — New shortcut enablingcore + introspection + migration + codemodefor schema development workflows- Code Mode Introspection/Migration Support —
sqlite.introspection.*andsqlite.migration.*groups added to sandbox API- Method aliases:
deps,toposort,cascade,snapshot,constraints,risks,setup,log,run,undo - Positional parameter support and help() examples for both groups
- Groups listed in
sqlite_execute_codetool description andServerInstructions.ts
- Method aliases:
- Tool Icons (MCP 2025-11-25) — All tools, resources, and prompts now include visual icons
- 8 group-level icons from Material Design Icons (CDN-hosted SVG via jsDelivr)
- Built-in server tools (
server_info,server_health,list_adapters) get a server icon - New
src/utils/icons.tsutility withgetToolGroupIcon()andSERVER_ICONS - Icon passthrough in both WASM and Native adapter
registerTool()/registerResource()/registerPrompt()methods McpIcontype added totypes/index.ts;iconsfield added toToolDefinition,ResourceDefinition,PromptDefinition- Dual HTTP Transport — HTTP transport now supports both Streamable HTTP (MCP 2025-03-26) and Legacy SSE (MCP 2024-11-05) protocols simultaneously
GET /sse— Opens Legacy SSE connection for backward-compatible clientsPOST /messages?sessionId=<id>— Routes messages to Legacy SSE transport- Cross-protocol guard: SSE session IDs rejected on
/mcpand vice versa
- Security Headers — All HTTP responses now include 7 security headers:
X-Content-Type-Options: nosniff,X-Frame-Options: DENY,Cache-Control: no-store,Content-Security-Policy,Permissions-Policy,Referrer-Policy,Strict-Transport-Security - Rate Limiting — Per-IP sliding-window rate limiting (100 requests/minute, health endpoint exempt)
- Body Size Enforcement — JSON body limited to 1 MB via
express.json({ limit }), returns 413 for oversized payloads - 404 Handler — Unknown paths now return
404 { error: "Not found" }instead of Express default HTML - Code Mode (Sandboxed Execution) — New
sqlite_execute_codetool for executing JavaScript in a sandboxed environment- Agents write code using
sqlite.*API to access all 7 tool groups (core, json, text, stats, vector, admin, geo) - 70-90% token reduction by replacing multiple sequential tool calls with a single code execution
- Dual sandbox support:
worker_threads(default, enhanced isolation) andvmmodule - Worker sandbox uses MessagePort RPC bridge for secure API proxy between threads
- Security: code validation against blocked patterns, rate limiting (60 exec/min), result sanitization (10MB cap), audit logging
- Built-in
help()for discoverability:sqlite.help()for groups,sqlite.<group>.help()for methods - Positional parameter support:
sqlite.core.readQuery("SELECT 1")maps to{ query: "SELECT 1" } - Method aliases for ergonomic use (e.g.,
sqlite.core.query()→readQuery) - New
codemodetool group added to all meta-group shortcuts (starter, analytics, search, spatial, minimal, full) - Environment variable
CODEMODE_ISOLATION=vm|workerto select sandbox mode (default:worker) - New files:
src/codemode/(types, security, sandbox, worker-sandbox, worker-script, sandbox-factory, api, index) - Updated:
ToolGrouptype,LogModule,ToolConstants,ServerInstructions, tool index - Auto-injected into all tool filter configurations (whitelist mode) — opt out with
-codemode sqlite_drop_indexTool — New core tool to drop indexes from the database- Validates index existence before dropping
- Supports
ifExistsflag (defaulttrue) for graceful no-op when index doesn't exist - Registered in core group with
DropIndexSchema/DropIndexOutputSchema - Added to
ToolConstants.ts,ServerInstructions.ts, and positional param map - Core tool count: 8 → 9 (minimal meta-group: 9 → 10)
- Agents write code using
- Server Host Binding — New
--server-hostCLI option andMCP_HOSTenvironment variable- Configures which host/IP the HTTP transport binds to (default:
0.0.0.0) - Use
--server-host 127.0.0.1to restrict to local connections only - Precedence: CLI flag >
MCP_HOSTenv var >HOSTenv var > default (0.0.0.0) - Essential for containerized deployments where binding to all interfaces is required
- Configures which host/IP the HTTP transport binds to (default:
-
Inline Schema Consolidation: Relocated 7 migration output schemas (
MigrationRecordEntry,MigrationInitOutputSchema,MigrationRecordOutputSchema,MigrationApplyOutputSchema,MigrationRollbackOutputSchema,MigrationHistoryOutputSchema,MigrationStatusOutputSchema) fromtools/migration/schemas.tsto centralizedoutput-schemas/migration.ts— the last tool group without dedicated output schema files. Original location now re-exports for backward compatibility. -
Inline Schema Consolidation: Extracted 9 inline
outputSchema: z.object()definitions from introspection tool handlers into centralizedoutput-schemas/introspection.ts—DependencyGraphOutputSchema,TopologicalSortOutputSchema,CascadeSimulatorOutputSchema,SchemaSnapshotOutputSchema,ConstraintAnalysisOutputSchema,MigrationRisksOutputSchema,StorageAnalysisOutputSchema,IndexAuditOutputSchema,QueryPlanOutputSchema. All output schemas are now consistently defined in centralized files with named exports — zero inline definitions remain across all tool groups. -
Inline Schema Consolidation: Extracted 8 remaining inline
outputSchema: z.object()definitions from tool handlers into centralizedoutput-schemas/files —virtual.ts(7 schemas:ListVirtualTablesOutputSchema,VirtualTableInfoOutputSchema,DropVirtualTableOutputSchema,CreateCsvTableOutputSchema,AnalyzeCsvSchemaOutputSchema,CreateRtreeTableOutputSchema,CreateSeriesTableOutputSchema),text.ts(1 schema:TextValidateOutputSchema), andstats.ts(1 schema:StatsHypothesisOutputSchema). All output schemas are now consistently defined in centralized files with named exports — zero inline definitions remain. -
Complexity Refactor: Addressed source code complexity by splitting files exceeding logical grouping boundaries into modular directories with barrel exports:
- Extracted query execution, initialization, and connection lifecycle handlers from
sqlite-adapter.ts. - modularized authentication routines in
middleware.tsandscopes.ts. - Refined administration and stats tools (
backup.ts,tracking.ts,vtable.ts,inference.ts). - Extracted resource, tool, and prompt registration logic from
database-adapter.ts.
- Extracted query execution, initialization, and connection lifecycle handlers from
-
Code Quality Audit: Addressed technical debt across the codebase by replacing generic
anycasts with type-safe structures, normalizing test file naming from.testtokebab-case, extracting massivenative-sqlite-adapter.tstooling logic intoregistration, and removing unsafe type imports. -
Code Quality Audit: Removed dead code by deleting unused barrel files (
src/auth/index.tsandsrc/transports/index.ts). -
Performance Audit: Disabled source maps generation in the production build to significantly reduce bundle size (from 3.7MB to 1.5MB), optimized sandbox serialization to reduce runtime memory allocations, and added caching to schema introspection tools via
SchemaManager. -
Unified Audit: Enabled code splitting in
tsup.config.tsto deduplicate shared modules across the 3 entry points. -
MCP Compliance: Added
openWorldHint: falseto all tool annotation presets andopenWorldHintto theToolAnnotationstype interface. -
MCP Compliance: Added
titleto built-in server tools (server_info,server_health,list_adapters). -
MCP Compliance: Added
errorfield toErrorResponseFieldsmixin (was 5 fields, now 6 per mcp-builder §2.2.2). -
MCP Compliance: Created
src/auth/transport-agnostic.tsre-exporting non-Express auth utilities for transport portability. -
MCP Compliance: Renamed
formatHandlerErrorResponse→formatHandlerErroracross all tool handlers, tests, and barrel exports per mcp-builder §2.2.2 single-formatter standard. Old name preserved as deprecated alias informat.ts. -
MCP Compliance: Wired prompt
argsSchemato SDK registration — prompts with required arguments now expose typed schemas viaprompts/list. All-optional and zero-arg prompts correctly omitargsSchemaper SDK gotcha (§1.4). -
MCP Compliance: Consolidated duplicate
ErrorFieldsMixin/ErrorResponseFieldsto single source of truth insrc/utils/errors/error-response-fields.tswith re-export alias. -
Help Resource Architecture: Replaced tiered
--instruction-levelCLI flag andINSTRUCTION_LEVELenv var with pull-basedsqlite://helpresources. RemovedinstructionLevelfromMcpServerConfig. Replaced monolithicserver-instructions.mdwith per-group.mdfiles insrc/constants/server-instructions/. Generate script updated to produce slimINSTRUCTIONSconstant +HELP_CONTENTmap. -
HSTS: Wired
--enable-hstsCLI flag andMCP_ENABLE_HSTSenv var to the HTTP transport — previously defined in types but never reachable from the CLI. -
Error Handling — Output Schema Migration — All 10 output schema files (~115 schemas) now include
ErrorFieldsMixinvia.extend(ErrorFieldsMixin.shape)- New
error-mixin.tsdefines shared mixin with all 6ErrorResponsefields (error,code,category,suggestion,recoverable,details) - Replaces inconsistent inline error fields (some schemas had
error+code+suggestion, others had none) - Ensures every tool's output schema can accommodate structured error responses
- New
-
Error Handling — Handler Migration to
formatHandlerError— ~108 catch blocks across ~25 handler files migrated to useformatHandlerError()directly- Eliminates Pattern A re-wrapping (
const structured = formatError(error); return { success: false, message: structured.error }) - Eliminates Pattern B inline error construction
- All handler catch blocks now use
return formatHandlerError(error)for consistent structured error responses - Affected groups: core, admin, text, json-helpers, json-operations, introspection, fts, codemode, stats, vector, geo, migration
- 3 synchronous handlers wrapped with
Promise.resolve()to satisfyhandler: () => Promise<unknown>type constraint
- Eliminates Pattern A re-wrapping (
-
Performance Audit Fix — Async File I/O — Replaced synchronous
fs.readFileSyncandfs.writeFileSyncwithfs.promises.readFileandfs.promises.writeFileinsqlite-adapter.tsto prevent event loop blocking during database initialization and teardown. -
Code Quality Audit — Standardized Error — Replaced an instance of generic
Errorinsqlite_stats_regression(inference.ts) withDbMcpErrorusingSTATS_INSUFFICIENT_SAMPLEandVALIDATIONcategory. -
Code Quality Audit — Logger Module Split — Split monolithic
logger.ts(543 lines) intoutils/logger/directorytypes.ts:LogLevel,LogModule,LogContexttype definitionserror-codes.ts:ErrorCodetype,createErrorCode(), andERROR_CODESconstant mapmodule-logger.ts:ModuleLoggerclass for module-scoped logginglogger.ts: CoreLoggerclass with sanitization and dual-mode outputindex.ts: Barrel re-export with default logger instance and env initialization- Updated 30 consumer imports across source and test files
-
Code Quality Audit — Enhanced Error Handling — Replaced 35+ instances of generic
throw new Error()with enhancedDbMcpError(and subclasses likeValidationError) across the codebase- Affected areas:
HttpTransport,DbMcpServer,SandboxPool,SchemaManager,native-sqlite-adapter, and numerous tool modules (window.ts,geo.ts,inference.ts,validate.ts, etc.) - Ensures all errors follow the structured
DbMcpErrorformat with appropriate module-prefixed error codes and ErrorCategory classifications
- Affected areas:
-
Code Quality Audit — Shared WAL/JSONB Helpers — Extracted
autoEnableWal()anddetectAndSetJsonbSupport()intosqlite-helpers.ts- Both WASM and native adapters now delegate to shared helpers instead of duplicating logic
-
Code Quality Audit — Native Query Executor — Extracted
nativeExecuteRead(),nativeExecuteWrite(),nativeExecuteGeneral()intonative-query-executor.ts- Mirrors the existing WASM
query-executor.tspattern;native-sqlite-adapter.tsreduced from 653 to ~555 lines
- Mirrors the existing WASM
-
Code Quality Audit — Transport Type Adapters — Created
type-adapters.tswithasIncoming()andasServerResponse()- Replaced 16 inline
as unknown ascasts acrosssession.ts
- Replaced 16 inline
-
Code Quality Audit — Query Validation Extraction — Extracted
validateQuery()andDANGEROUS_SQL_PATTERNSintoquery-validation.tsdatabase-adapter.tsreduced from 564 to ~520 lines
-
Code Quality Audit — LogModule Type — Added
NATIVE_SQLITEandHTTPto theLogModuleunion type -
Code Quality Audit — JSON-RPC Constants — Added
JSONRPC_SERVER_ERRORandJSONRPC_INTERNAL_ERRORtotransports/http/types.ts- Replaced inline magic numbers in
session.ts
- Replaced inline magic numbers in
-
Code Quality Audit — Base Class
ensureConnected()— ConcreteensureConnected()method onDatabaseAdapterwithConnectionError- Both adapters override with
protected overridecallingsuper.ensureConnected()+ db-null check - Eliminates duplicated connection-check logic between WASM and native adapters
- Both adapters override with
-
Code Quality Audit — Transaction Method Extraction — Extracted 6 transaction functions into
transaction-methods.tsbeginTransaction,commitTransaction,rollbackTransaction,savepoint,releaseSavepoint,rollbackToSavepointnative-sqlite-adapter.tsdelegates via thin one-liner methods; reduces file from 645 to ~605 lines
-
Code Quality Audit — PRAGMA Deduplication — Extracted
PragmaExecutorinterface andapplyCommonPragmas()intosqlite-helpers.ts- Eliminates duplicated walMode/foreignKeys/busyTimeout/cacheSize PRAGMA logic between WASM and native adapters
- Both adapters now delegate to the shared helper with a thin PragmaExecutor wrapper
-
Code Quality Audit — Extension Loading Extraction — Created
sqlite-native/extensions.tswithloadSpatialite()andloadCsvExtension()- Moved SpatiaLite and CSV extension loading (candidate paths, Windows PATH augmentation, try-next-path loop) out of
native-sqlite-adapter.ts native-sqlite-adapter.tsreduced from 731 to 578 lines;sqlite-adapter.tsfrom 556 to 484 lines
- Moved SpatiaLite and CSV extension loading (candidate paths, Windows PATH augmentation, try-next-path loop) out of
-
Code Quality Audit — Row Mapping Deduplication — Extracted
rowsFromSqlJsResult()helper insqlite-adapter.ts- Replaced 2 identical row-mapping closures in
executeReadQueryandexecuteQuery
- Replaced 2 identical row-mapping closures in
-
Code Quality Audit — Query Executor Extraction — Extracted
executeRead,executeWrite,executeGeneralintoadapters/sqlite/query-executor.tssqlite-adapter.tsreduced from 679 to ~510 lines; adapter retains validation, connection, and schema cache responsibility
-
Code Quality Audit — HTTP Timeout Constants — Named magic timeout values in
transports/http/types.tsHTTP_REQUEST_TIMEOUT_MS(120s),HTTP_KEEP_ALIVE_TIMEOUT_MS(65s),HTTP_HEADERS_TIMEOUT_MS(66s)transport.tsnow imports named constants instead of using inline numbers
-
Code Quality Audit — Types File Split — Split
types/index.ts(528 lines) into 5 sub-modulesdatabase.ts,server.ts,auth.ts,filtering.ts,adapter.tswith barrel re-export- Zero consumer import changes — all continue importing from
types/index.js
-
Code Quality Audit — Fixed stale
--postgresqlreference in CLI no-database warning; server only supports SQLite -
Code Quality Audit — Removed extraneous blank lines in
sqlite-adapter.ts -
Code Quality Audit — Removed duplicate "Server Host Binding" CHANGELOG entry
-
Code Quality Audit — Native Adapter Error Handling — Replaced plain
Errorthrows with typed error classes innative-sqlite-adapter.tsconnect():ConfigurationErrorfor type mismatch,ConnectionErrorfor connection failuresexecuteReadQuery()/executeWriteQuery():QueryErrorwith SQL context and module-prefixed error codes- Matches the WASM adapter's error handling, which already used typed errors
-
Code Quality Audit — Extension Loading Deduplication — Extracted
tryLoadExtension()helper andEXTENSIONS_DIRconstant innative-sqlite-adapter.ts- SpatiaLite and CSV extension loading shared identical try-next-path loop, logging, and
__dirnamecomputation - Both now call the shared helper; ~50 lines of duplication removed
- SpatiaLite and CSV extension loading shared identical try-next-path loop, logging, and
-
Code Quality Audit — Migration Record Mapping — Extracted
toMigrationRecord()intomigration/schemas.ts- Replaced 5 identical inline row→record mapping blocks in
tracking.ts
- Replaced 5 identical inline row→record mapping blocks in
-
Code Quality Audit — API Constants Extraction — Moved
METHOD_ALIASES,GROUP_EXAMPLES,POSITIONAL_PARAM_MAP,GROUP_PREFIX_MAP,KEEP_PREFIX_GROUPSfromapi.tsto newcodemode/api-constants.tsapi.tsreduced from 610 to ~330 lines
-
Code Quality Audit —
validateColumnExistsDeduplication — Extracted sharedvalidateColumnExists()andvalidateColumnsExist()intoadapters/sqlite/tools/column-validation.ts- Removed identical 40-line copies from
geo.ts,text/helpers.ts, andstats/helpers.ts - All three modules now re-export from the shared utility; no consumer import changes needed
- Removed identical 40-line copies from
-
Code Quality Audit —
normalizeParamsDeduplication — Extracted sharednormalizeSqliteParams()intoadapters/sqlite-helpers.ts- Removed identical copies from
sqlite-adapter.tsandnative-sqlite-adapter.ts - Both adapters now import from the shared module
- Also removed unnecessary
DatabaseType as DbTypealias in native adapter
- Removed identical copies from
-
Code Quality Audit —
DatabaseTypeNarrowing — NarrowedDatabaseTypeunion from 6 variants (sqlite | postgresql | mysql | mongodb | redis | sqlserver) to"sqlite"only- Other database types would require separate MCP server projects; unused variants were dead code
-
Code Quality Audit —
DatabaseConfigCleanup — Removed unusedhost,port,database,username,passwordfields- SQLite uses
connectionString(file path) andoptions; relational connection fields were never referenced
- SQLite uses
-
Code Quality Audit —
SqliteAdapter.getInfo()Override Removed — Deleted override that silently droppedcapabilitiesandtoolGroupsfields from the parentDatabaseAdapter.getInfo() -
Code Quality Audit — Magic Values Named — Replaced inline magic numbers with named constants
geo.ts:111→KM_PER_DEGREE_LAT(km per degree of latitude for bounding box pre-filter)worker-sandbox.ts:1000→TIMEOUT_GRACE_MS(extra grace period for worker cleanup)
-
Code Quality Audit — Stale TODO Removed — Removed misleading
TODO: Add other database adaptersfromcli.ts- Additional adapters belong in separate MCP server projects, not this codebase
-
File Naming Convention (Round 2) — Renamed 3 camelCase files to lowercase-with-dashes per project convention
- Source:
insightsManager.ts→insights-manager.ts,resourceAnnotations.ts→resource-annotations.ts - Test:
insightsManager.test.ts→insights-manager.test.ts - Updated 6 files with corrected import paths
- Source:
-
isDDL()Helper Deduplication — Extracted sharedisDDL()function intoadapters/sqlite-helpers.ts -
Version Constant Deduplication —
VERSIONandNAMEnow read frompackage.jsonat runtime via newversion.tsmodule- Eliminated 3 hardcoded
"1.0.2"strings inindex.ts,mcp-server.ts, andcli.ts index.tsre-exports fromversion.ts;mcp-server.tsandcli.tsimport directly- Future version bumps only need to update
package.json
- Eliminated 3 hardcoded
-
File Size Refactoring — Split 4 oversized files into modular subdirectories
utils/errors.ts(559 lines) →errors/directory (5 modules + barrel), updated 43 import pathsintrospection/diagnostics.ts(738 lines) →diagnostics/directory (3 tool modules + barrel)introspection/analysis.ts(720 lines) →analysis/directory (3 tool modules + barrel)introspection/graph.ts(590 lines) →graph/directory (helpers + tools + barrel)
-
File Naming Convention — Renamed 16 PascalCase files (11 source + 5 test) to lowercase-with-dashes per project convention
- Source:
DatabaseAdapter.ts,McpServer.ts,SqliteAdapter.ts,NativeSqliteAdapter.ts,SchemaManager.ts,ToolFilter.ts,ToolConstants.ts,ServerInstructions.ts,OAuthResourceServer.ts,AuthorizationServerDiscovery.ts,TokenValidator.ts - Tests:
DatabaseAdapter.test.ts,SchemaManager.test.ts,SqliteAdapter.test.ts,NativeSqliteAdapter.test.ts,ToolFilter.test.ts - Updated 82 files with corrected import paths
- Source:
-
Dead Code Cleanup — Removed extra blank lines in
native-sqlite-adapter.ts -
Dockerfile Builder Stage — Removed unnecessary
apk upgrade --no-cachefrom builder stage (DK-3)- Builder is discarded after multi-stage build; security patches only needed in production stage
- Saves ~5-10s per Docker build
-
Dockerfile Label Accuracy — Fixed tool count in LABEL from 124 to 139 (DK-2)
-
Tier 2 File Refactoring — Split 4 large files (700–986 lines) into modular directory structures
- Phase 1 — Adapter Deduplication: Extracted shared
registerTool/registerResource/registerPromptlogic intoDatabaseAdapterbase class, reducingNativeSqliteAdapter.ts(956→727) andSqliteAdapter.ts(945→721) - Phase 2 — Transport Split: Split
http.ts(986 lines) intohttp/directory with 6 files:types.ts,middleware.ts,session.ts,oauth.ts,transport.ts,index.ts - Phase 3 — Tool File Splits: Split 3 tool files into directory modules:
spatialite.ts(915) →spatialite/(4 files:schemas.ts,loader.ts,tools.ts,index.ts)vector.ts(826) →vector/(4 files:schemas.ts,helpers.ts,tools.ts,index.ts)core.ts(770) →core/(4 files:queries.ts,tables.ts,indexes.ts,index.ts)
- All consumer imports updated (6 source files + 1 test); no public API changes
- Phase 1 — Adapter Deduplication: Extracted shared
-
Configurable CORS Origins — CORS refactored from hardcoded
Access-Control-Allow-Origin: *to configurablecorsOriginsarray; supports explicit origins withAccess-Control-Allow-Credentials: true; removed duplicated CORS middleware -
Root Endpoint —
GET /now lists Legacy SSE endpoints and updated description to "dual HTTP transport" -
Deterministic Error Handling — Structured error responses across all tools
registerTool()catch block now usesformatError()to surfacecode,category,suggestion,recoverablefields- Applies to both WASM (
SqliteAdapter) and native (NativeSqliteAdapter) adapters - Codemode error paths enriched:
CODEMODE_VALIDATION_FAILED,CODEMODE_RATE_LIMITED,CODEMODE_EXECUTION_FAILED - Added 4 codemode-specific patterns to
ERROR_SUGGESTIONSfor auto-suggestion matching
-
Core Tool Handler-Level Error Handling — 5 core tool handlers now catch errors locally and return
{success: false}responsessqlite_read_query,sqlite_write_query,sqlite_describe_table,sqlite_create_index: Catch errors withformatError()and return structured{success: false, error, code, suggestion}instead of propagating asisError: trueMCP exceptionssqlite_drop_table: Checks table existence before DROP; returns"does not exist (no changes made)"whenifExistsis true and table is absent, or{success: false}whenifExistsis falsesqlite_describe_table: Pre-checks table existence and returnsTABLE_NOT_FOUNDerror code instead of genericUNKNOWN_ERRORsqlite_get_indexes: Validates table existence whentableNameis specified; returns{success: false, code: "TABLE_NOT_FOUND"}instead of empty{success: true}
-
Text Tool Handler-Level Error Handling — All 13 text tool handlers now catch errors locally and return
{success: false}responsessqlite_regex_match,sqlite_regex_extract,sqlite_text_split,sqlite_text_concat,sqlite_text_replace,sqlite_text_trim,sqlite_text_case,sqlite_text_substring,sqlite_fuzzy_match,sqlite_phonetic_match,sqlite_text_normalize,sqlite_text_validate,sqlite_advanced_search: Catch errors withformatError()and return structured{success: false, error, code, suggestion}instead of propagating as raw MCP exceptions- Mirrors the same pattern already applied to core and JSON tool groups
-
Text Tool Column Existence Validation — All 13 text tools now validate column existence before query execution
- Prevents silent success on nonexistent columns (SQLite treats double-quoted nonexistent identifiers as string literals)
- Returns
{success: false, code: "COLUMN_NOT_FOUND"}with suggestion to usesqlite_describe_table validateColumnExists()usesPRAGMA table_info()to verify column presencevalidateColumnsExist()handles multi-column tools (sqlite_text_concat)- Identifier validation (
sanitizeIdentifier) runs first for security, then column existence check - 12 new error path tests added for nonexistent column on valid table scenarios
-
Stats Tool Handler-Level Error Handling — All 13 stats tool handlers now catch errors locally and return
{success: false}responsessqlite_stats_basic,sqlite_stats_count,sqlite_stats_group_by,sqlite_stats_histogram,sqlite_stats_percentile,sqlite_stats_correlation,sqlite_stats_top_n,sqlite_stats_distinct,sqlite_stats_summary,sqlite_stats_frequency,sqlite_stats_outliers,sqlite_stats_regression,sqlite_stats_hypothesis: Catch errors withformatError()and return structured{success: false, error, code, suggestion}instead of propagating as raw MCP exceptions- Mirrors the same pattern already applied to core, JSON, and text tool groups
-
Stats Tool Column Existence Validation — All 13 stats tools now validate column existence before query execution
sqlite_stats_summaryvalidates user-specified columns; auto-detected columns skip validationsqlite_stats_correlationvalidates bothcolumn1andcolumn2;sqlite_stats_regressionvalidates bothxColumnandyColumnsqlite_stats_hypothesisvalidatescolumn,column2(ttest_two), andgroupColumn(chi_square)- 15 new error path tests added for nonexistent table and column scenarios
-
Security Test Pattern Update — Updated security integration tests for stats tool structured error handling
tool-integration.test.ts: 57 stats injection tests now useassertRejectsInjection()helper accepting either throws or{success: false}responsesidentifier-integration.test.ts: 4 stats identifier injection tests updated fromrejects.toThrow()to structured error assertions- Fixed
stats_group_byidentifier test using wrong parameter names (column/groupColumn→valueColumn/groupByColumn/stat)
-
Compact JSON Serialization (R-1) — Tool responses now use compact
JSON.stringify(result)instead of pretty-printedJSON.stringify(result, null, 2)- Reduces serialization overhead by ~15-20% on large payloads; MCP clients parse JSON programmatically
- Error responses retain pretty-print for debugging readability
-
Incremental TypeScript Builds (B-1) — Added
incremental: trueandtsBuildInfoFiletotsconfig.json- Subsequent builds only recheck changed files, significantly reducing dev-loop build times
-
Vitest Thread Pool (T-1) — Configured
pool: "threads"invitest.config.ts- Enables worker thread execution for test parallelism on multi-core machines
-
isDDL()Helper Extraction (S-2/R-4) — Replaced 3× duplicated DDL detection blocks with module-scopeisDDL()function- Eliminates redundant
sql.trim().toUpperCase()allocations inSqliteAdapter.tsandNativeSqliteAdapter.ts
- Eliminates redundant
-
SchemaManager Array Pre-Allocation (R-7) —
getAllIndexes()now pre-allocates result array withnew Array(rows.length)- Avoids incremental
push()resizing; improved documentation of PRAGMA batching constraints
- Avoids incremental
-
CI
node_modulesCaching (CI-1) — Addedactions/cache@v4fornode_modulesinlint-and-test.yml- Keyed on
package-lock.jsonhash per Node.js version; skipsnpm cion cache hit (~20-30s savings per run)
- Keyed on
-
CI Benchmark Tracking (CI-2) — New
benchmarksjob inlint-and-test.yml(main branch only)- Runs
npm run benchand uploads results as artifacts with 30-day retention for regression detection
- Runs
-
NativeSqliteAdapter SchemaManager Integration — Schema metadata operations now use TTL-based caching
listTables(),describeTable(),getSchema(),getAllIndexes()delegate throughSchemaManager(5s TTL)- Eliminates redundant
PRAGMA table_info()queries on every metadata request - Auto-invalidates schema cache on DDL operations (
CREATE,ALTER,DROP) - Matches the caching pattern already used by the WASM
SqliteAdapter
-
Cached Tool Definitions —
NativeSqliteAdapter.getToolDefinitions()now lazily caches results- Tool definitions are immutable per adapter instance; avoids 13-way array spread on repeat calls
-
Logger Taint-Breaking Optimization —
writeToStderr()uses"".concat()instead of per-character copy- Previous O(n) character-by-character array+join replaced with single string concatenation
- Still breaks CodeQL taint tracking without the allocation overhead
-
Logger Sensitive Key Matching — Pre-computed
SENSITIVE_KEYS_ARRAYat module scope- Avoids spreading
Setinto a new array on every context key duringsanitizeContext()
- Avoids spreading
-
Logger Regex Pre-Compilation —
sanitizeMessage()andsanitizeStack()regex patterns hoisted to module scope- Avoids re-constructing
RegExpobjects (viaString.fromCharCode()) on every log call
- Avoids re-constructing
-
SQL Validation Regex Pre-Compilation —
DANGEROUS_SQL_PATTERNShoisted to module scope inDatabaseAdapter.ts- Avoids re-allocating 5
RegExpobjects pervalidateQuery()call
- Avoids re-allocating 5
-
CORS Preflight Caching — Added
Access-Control-Max-Age: 86400to OPTIONS responses- Browsers cache preflight results for 24 hours, reducing repeated OPTIONS roundtrips
-
Docker HTTP Healthcheck — Healthcheck now validates
/healthendpoint for HTTP transport- Falls back to basic Node.js check for stdio mode
-
Bumped
@eslint/jsfrom 9.39.2 to 10.0.1 (major) -
Bumped
@modelcontextprotocol/sdkfrom 1.25.3 to 1.27.1 -
Bumped
@types/nodefrom 25.2.0 to 25.5.0 -
Bumped
@vitest/coverage-v8from 4.0.18 to 4.1.0 -
Bumped
better-sqlite3from 12.6.2 to 12.8.0 -
Bumped
eslintfrom 9.39.2 to 10.0.3 (major) -
Bumped
globalsfrom 17.3.0 to 17.4.0 -
Bumped
josefrom 6.1.3 to 6.2.1 -
Bumped
rimraffrom 6.1.2 to 6.1.3 -
Bumped
sql.jsfrom 1.13.0 to 1.14.1 -
Bumped
typescript-eslintfrom 8.54.0 to 8.57.1 -
Bumped
vitestfrom 4.0.18 to 4.1.0 -
Removed unused
dotenvproduction dependency (never imported in source) -
Removed unused
pgand@types/pgdependencies (never imported in source) -
Dockerfile
tardependency pinned to 7.5.11 for security compliance -
Bumped
@types/sql.jsfrom 1.4.9 to 1.4.10 -
Bumped
josefrom 6.2.1 to 6.2.2
- Missing Annotations: Added
readOnly(...)MCP annotations to all 6 window function tools (sqlite_window_row_number,sqlite_window_rank,sqlite_window_lag_lead,sqlite_window_running_total,sqlite_window_moving_avg,sqlite_window_ntile) — these were the only stats-group tools withoutannotations, causing the code mode readonly guard (fail-closedisWriteTool()) to incorrectly block them inreadonly: truemode despite being pure SELECT queries. - Missing Annotations: Added
write(...)MCP annotations to all 7 transaction tools (sqlite_transaction_begin,sqlite_transaction_commit,sqlite_transaction_rollback,sqlite_transaction_savepoint,sqlite_transaction_release,sqlite_transaction_rollback_to,sqlite_transaction_execute) — discovered by the newtool-annotations.test.tsinvariant test. While the fail-closedisWriteTool()guard correctly blocked these in readonly mode (they are write tools), the missing annotations violated the structural invariant and prevented proper tool discoverability. - Output Schema Strictness: Made domain-specific fields optional in 24 output schemas across
core.ts(5),admin.ts(9),virtual.ts(9), andnative.ts(1) — fields likerowCount,rows,tables,count,columns,indexes,integrity,databases,options,message,durationMs,insightCount,statementsExecutedwere required but absent from error responses ({success: false, error: "..."}), causing raw MCP-32602output validation errors on error paths. Discovered by the newtool-output-schemas.test.tsinvariant test. - Output Schema Enforcement: Wired existing
TransactionBeginOutputSchema,TransactionCommitOutputSchema,TransactionRollbackOutputSchema,TransactionSavepointOutputSchema,TransactionReleaseOutputSchema,TransactionRollbackToOutputSchema, andTransactionExecuteOutputSchemato their corresponding 7 transaction tool definitions — schemas were defined innative.tsbut never referenced, so the MCP SDK could not enforce output validation on these tools. - Input Coercion: Added
z.preprocess()coercion for numeric parameters (limit,gridSize,srid,distance,simplifyTolerance,centerLat,centerLon,radius,minLat,maxLat,minLon,maxLon,lat1–lon2) and enum parameters (unit,geometryType,analysisType,action,format,operation) in geo and SpatiaLite schemas — 22 params total. Non-numeric strings fall back to defaults, invalid enum values fall back to defaults instead of producing raw MCP-32602validation frames. - Input Coercion: Added
z.preprocess(coerceBoolean, ...)coercion for boolean parameters (forceReload,excludeSelf,includeGeometry) in SpatiaLite schemas — non-boolean strings now coerce to defaults instead of producing raw MCP-32602validation frames. - Validation Leaks: Fixed Zod output schema errors in JSON tools (
sqlite_json_valid,sqlite_json_validate_path) and core tools (sqlite_drop_table,sqlite_create_index,sqlite_drop_index) that caused the server to return raw MCP-32602validation frames instead of structured domain errors, by marking conditional message fields as optional. - Input Coercion: Handled invalid numeric input types gracefully in JSON operations (
sqlite_json_each,sqlite_json_query,sqlite_json_analyze_schema,sqlite_json_storage_info) and migration tools (sqlite_migration_rollback,sqlite_migration_history) by replacingz.coerce.number()withz.preprocess()forlimit,sampleSize,id, andoffsetparameters — non-numeric values now silently fall back to defaults instead of producing raw MCP-32602validation frames. - Validation Leaks: Fixed Zod output schema errors in text tools (
sqlite_regex_match,sqlite_regex_extract,sqlite_text_split,sqlite_text_replace,sqlite_text_normalize,sqlite_text_validate) and FTS tools (sqlite_fts_create,sqlite_fts_search,sqlite_fts_rebuild,sqlite_fts_match_info) that caused raw MCP-32602output validation errors on error paths, by marking non-error fields as optional so{success: false, error: "..."}responses pass output validation. - Input Coercion: Added
z.preprocess()coercion for all numeric parameters in text tool schemas (limit,maxDistance,groupIndex,start,length,fuzzyThreshold,maxInvalid) and FTS searchlimit— non-numeric string values now silently fall back to defaults instead of producing raw MCP-32602input validation frames. - Input Coercion: Added
z.preprocess()coercion for all numeric parameters in stats schemas (limit,buckets,n,threshold,maxOutliers,degree,expectedMean) and window function schemas (limit,offset,windowSize,buckets) — 19 params total. MovedmaxOutliersmin/max refinements (.min(1).max(500)) to handler validation to avoid Zod refinement leaks. - Input Coercion: Added
z.preprocess()coercion for numeric parameters (limit,sampleSize,dimensions) and enum parameters (metric) in vector tool schemas — non-numeric strings fall back to defaults, invalid metric values fall back to"cosine"default instead of producing raw MCP-32602validation frames. - Input Coercion: Added
z.preprocess()coercion for required array parameters in vector tool schemas (vector,queryVector,vector1,vector2,items,ids) — non-array inputs are coerced to empty arrays to pass SDK.partial()validation, then handler-level guards reject them with structured errors instead of raw MCP-32602validation frames. - Dimension Validation: Fixed
sqlite_vector_batch_storeonly validating the first item's vector dimensions against the table schema — now validates all items individually with per-item error reporting (e.g.,"Dimension mismatch at item[1]"). - Input Coercion: Added
z.preprocess()coercion for numeric parameters in admin schemas (maxErrors,mask) and virtual table schemas (limit,start,stop,step,sampleRows,dimensions) — 12 params total. Moveddimensionsmin/max refinements (.min(2).max(5)) to handler validation to prevent Zod refinement leaks. - Input Coercion: Added
z.preprocess()coercion fortimeoutparameter insqlite_execute_codeand moved.int().min(1000).max(30000)refinements to handler validation. - Refinement Leaks: Removed
.regex()fromSavepointSchema.namein transaction tools — handler already validates with inline regex check. Prevents raw MCP-32602on invalid savepoint names. - Refinement Leaks: Added
z.preprocess()enum coercion forBeginTransactionSchema.mode— invalid enum values now coerce toundefinedand fall to the"deferred"default instead of producing raw MCP-32602validation frames. - Error Handling: Added missing
try/catchwrappers to admin handlers (integrityCheck,pragmaCompileOptions,pragmaDatabaseList,pragmaOptimize,dbstat,vacuum) — uncaught errors now return structured{success: false}responses viaformatHandlerError. - JSON Serialization: Fixed an issue in
sqlite_json_querywhere querying a column converted to JSONB would return the raw binary Buffer instead of the parsed JSON string by explicitly wrapping the column selection injson(). - PRAGMA/EXPLAIN LIMIT: Fixed
sqlite_read_queryappendingLIMIT 1000to PRAGMA and EXPLAIN statements, causing syntax errors. Safety limit injection now only applies to SELECT and WITH queries. - Instruction Generation: Fixed
enabledToolsset in server constructor passing group names (e.g.,"core","json") instead of actual tool names, causing the Active Tools summary atfullinstruction level to never match any tools. - Restore Data Loss: Fixed
sqlite_restoresilently dropping user-created indexes, views, and triggers during backup→restore cycles. The handler only restored tables (type='table'fromsqlite_master), permanently losing all other schema objects. Now restores indexes, views, and triggers from the backup source after table restoration. - Error Formatting: Standardized error handling across 11 admin/virtual tool handlers (
create_view,drop_view,generate_series,create_rtree_table,create_series_table,virtual_table_info,drop_virtual_table,pragma_table_info,append_insight,dbstat,vacuum,analyze_csv_schema,create_csv_table,list_virtual_tables,list_views,transaction_execute) — replaced rawerror.message(which produces unreadable Zod JSON arrays for validation errors) withformatHandlerError()for clean structured error responses. - Empty Path Validation: Added pre-validation guards to
sqlite_backup,sqlite_restore, andsqlite_verify_backup— empty/blank path strings now return clear"targetPath/sourcePath/backupPath is required"errors instead of confusing CWD resolution errors. - Test Prompt Corrections: Fixed 15 parameter name mismatches in the admin group test checklist (
test-group-tools.md):viewName/selectQueryfor views,tableNamefor virtual tables,targetPath/sourcePath/backupPathfor backup tools,filePathfor CSV tools,insightforappend_insight,pragmaforpragmaSettings, plain string array fortransaction_execute. Added requiredstart/stopparams forcreate_series_table, noted it creates a regular table (gotcha #15), and added absolute path warnings for backup and CSV tools. - Extension Path Resolution: Fixed
EXTENSIONS_DIRinextensions.tsresolving to the wrong directory after tsup code splitting — the relative path../../../extensionswas correct for the source tree depth (3 levels) but wrong for compiled output indist/(1 level). Replaced withfindProjectRoot()that walks up from the compiled file's directory to locatepackage.json, making CSV and future extension loading resilient to any bundler output structure. SpatiaLite was unaffected because it loaded viaSPATIALITE_PATHenv var. - Validation Leak: Fixed
sqlite_pragma_settings({})producing a raw MCP error by movingPragmaSettingsSchema.parse()inside thetry/catchblock — Zod validation errors now return structured{success: false}responses. - Error Field Consistency: Changed error field from
messagetoerrorin{success: false}responses forsqlite_verify_backup,sqlite_create_rtree_table,sqlite_create_series_table, andsqlite_transaction_execute— all error responses now consistently use theerrorfield per structured error convention. - Payload Optimization: Changed
sqlite_dbstatdefault forexcludeSystemTablesfromfalsetotrue— SpatiaLite system tables (37 objects includingspatial_ref_sysat 1434 pages) are now excluded by default, dramatically reducing response size. - Misleading Note: Fixed
sqlite_pragma_database_listshowing a "WASM virtual filesystem paths" note in Native mode on Windows — the path comparison now normalizes slashes before comparing, so the note only appears when internal paths genuinely differ (i.e., in WASM mode). - Error Field Consistency: Fixed
sqlite_append_insightempty-insight error response usingmessageinstead oferrorfield for{success: false}responses — now consistent with the structured error convention used by all other tools. - Test Prompt: Fixed
test-tools.mditem 9 annotation verification instruction from uncallabletools/listprotocol method to the existingtest-tool-annotations.mjsterminal script. Fixed duplicate item numbering (two item 9s) and broke items out of the CAUTION blockquote where they were incorrectly nested. - Validation Leak: Fixed
sqlite_execute_code({})producing a raw MCP error by movingExecuteCodeSchema.parse()inside thetry/catchblock — Zod validation errors now return structured{success: false}responses. Also mademetricsoptional inExecuteCodeOutputSchemaso error responses without metrics pass output schema validation. - Input Coercion: Added
z.preprocess()coercion for enum parameters in introspection tool schemas —operation(sqlite_cascade_simulator),direction(sqlite_topological_sort),sectionsarray (sqlite_schema_snapshot), andchecksarray (sqlite_constraint_analysis). Invalid enum values now coerce to defaults or are filtered out instead of producing raw MCP-32602validation frames. - Payload Optimization: Added
excludeSystemTablesparameter (default:true) tosqlite_schema_snapshot,sqlite_storage_analysis,sqlite_index_audit, andsqlite_constraint_analysis. SpatiaLite system tables, views, indexes, and triggers are now excluded by default, reducing response sizes by 47–91% in databases with SpatiaLite loaded. PassexcludeSystemTables: falseto restore the previous behavior. - Error Message Leak: Fixed
sqlite_spatialite_queryexposing internal better-sqlite3 implementation detail ("This statement does not return data. Use run() instead") when called with non-SELECT statements — now returns a clear"This tool only supports SELECT queries"message withQUERY_NOT_SELECTerror code. - Silent Enum Coercion: Fixed
sqlite_spatialite_indexsilently coercing invalidactionvalues (e.g.,"invalid_action") to the default"create"instead of returning a validation error. Replacedz.preprocess(coerceIndexAction, z.enum(...))withz.string()+ handler-level validation, consistent with the pattern used byanalysisType,operation, andformatin other SpatiaLite tools. - Output Schema Leak: Fixed
sqlite_cascade_simulatorwithcompact: trueproducing a raw MCP-32602output validation error — thepathfield in the output schema was required butcompactmode strips it from affected entries. Madepathoptional inCascadeSimulatorOutputSchema. - Payload Optimization: Added
excludeSystemTablesparameter (default:true) tosqlite_dependency_graphandsqlite_topological_sort. SpatiaLite system tables are now excluded by default, reducingdependency_graphfrom8KB→1.5KB andtopological_sortfrom3.5KB→0.7KB in databases with SpatiaLite loaded. PassexcludeSystemTables: falseto restore the previous behavior. - Output Schema Leak: Fixed
sqlite_geo_distancereturningfromandtocoordinate objects not declared inGeoDistanceOutputSchema— theadditionalProperties: falseconstraint caused the MCP framework to reject all successful responses with-32602. Removed redundant coordinate echo fields. - Field Naming: Fixed
sqlite_geo_nearbyusing_distancefield name on result items instead ofdistancedeclared inGeoWithinRadiusOutputSchema— clients relying on the schema-declared field would find it absent. - Strict Schema Leak: Removed
.strict()from all tool input schemas across all groups — core (10), json (14), stats/window (6), admin/transactions (7+1), geo/SpatiaLite (7), migration (2).additionalProperties: falsecaused the MCP SDK to reject unrecognized keys with raw-32602errors before handlers could catch them. - Error Consistency: Standardized ~20 error return paths across SpatiaLite tool handlers (
tools.ts,analysis.ts) to includecode,category, andrecoverablefields — previously returned bare{success: false, error: "..."}without the structured metadata used by all other tool groups. Fixedsqlite_spatialite_loadfailure response usingmessagefield instead oferrorfield. - Output Schema Leak: Fixed
sqlite_json_validandsqlite_json_validate_pathreturning raw MCP-32602output validation errors on every call — output schemas were missingsuccess,message,path, andissuesfields that the handlers return. - Output Schema Leak: Fixed
sqlite_optimize,sqlite_vacuum, andsqlite_analyze_csv_schemareturning raw MCP-32602output validation errors — output schemas were missingdurationMs,message, andwasmLimitationfields that the handlers return. - Phantom Tool Names: Fixed 11 non-existent tool names in help resource source files (
stats.md,text.md,geo.md) that would mislead agents into calling tools that don't exist. Removedsqlite_stats_covariance,sqlite_stats_z_score,sqlite_stats_moving_average,sqlite_text_pad,sqlite_text_template,sqlite_text_similarity,sqlite_text_word_count,sqlite_fts_count,sqlite_spatialite_status. Renamedsqlite_window_lead_lag→sqlite_window_lag_lead. Added missing real tools to help content. - Code Mode Groups: Fixed
gotchas.mdlisting only 7 Code Mode API groups — added missingsqlite.introspectionandsqlite.migrationwhich are real groups exposed by the sandbox API. - Validation Leak: Fixed
sqlite_json_normalize_columnproducing a raw MCP-32602error whenoutputFormatreceives an invalid enum value (e.g.,"invalid_format"). Replacedz.enum()in the schema withz.string()and handler-side validation, consistent with the established pattern for enum coercion. - Output Schema Alignment: Added missing
warningfield toJsonSetOutputSchemaandJsonRemoveOutputSchema— handlers return awarningproperty when 0 rows are affected, but the output schema did not declare it. Added missingfirstErrorDetailfield toJsonNormalizeColumnOutputSchema. ChangedoutputFormatinJsonNormalizeColumnOutputSchemafromz.enum()toz.string()to match the input schema change. - Missing Value Guards: Added explicit
undefinedguards for payload parameters (valueinsqlite_json_set,sqlite_json_array_append,sqlite_json_update;mergeDatainsqlite_json_merge;datainsqlite_json_insert) — the SDK's.partial()makes all params optional, so omitting these previously caused a cryptic"Cannot read properties of undefined"error instead of a clear"Missing required parameter: <name>"structured response. - Input Coercion: Fixed
sqlite_text_substringstartparameter producing a raw MCP-32602error when receiving wrong-type input (e.g.,"abc"). Changed inner schema from requiredz.number()toz.number().optional()and added handler-side validation so the preprocess coercion-to-undefined path returns a structured error. - Output Schema Leak: Fixed
sqlite_text_validatereturning undeclaredtruncatedfield when invalid results exceedmaxInvalid— addedtruncated: z.boolean().optional()to the inline output schema. - Silent Enum Coercion: Fixed
sqlite_vector_searchandsqlite_vector_distancesilently coercing invalidmetricvalues (e.g.,"invalid_metric") to the default"cosine"instead of returning a validation error. Replacedz.preprocess(coerceMetric, z.enum(...))withz.string()+ handler-level validation, consistent with the pattern used for SpatiaLiteactionand JSONoutputFormat. - E2E Test Flakiness: Fixed intermittent 429 rate-limit and timeout failures in the Playwright test suite by bumping
MCP_RATE_LIMIT_MAXfrom 1000 to 10000 (5× headroom), increasing global test timeout to 60s, and adding retry-with-backoff logic to thecreateClient()helper. - Raw MCP Error: Fixed
sqlite_analyze_csv_schemapropagating a raw MCP error when the CSV file does not exist at an absolute path — thetryblock had nocatch, only afinally. Added acatchblock returning structured{success: false, error: "..."}. Also changedmessage→errorin relative-path and WASM-unavailable error returns for field consistency. - Output Schema Wiring: Wired
outputSchemafor 6 window function tools (sqlite_window_row_number,sqlite_window_rank,sqlite_window_lag_lead,sqlite_window_running_total,sqlite_window_moving_avg,sqlite_window_ntile) — schemas were defined innative.tsbut never referenced. Updated 6 named schemas to match handler return shapes (addedrankType,direction,valueColumn,windowSize,buckets; maderowCount/rowsoptional). - Output Schema Wiring: Created 7 new SpatiaLite output schemas (
SpatialiteLoadOutputSchema,SpatialiteCreateTableOutputSchema,SpatialiteQueryOutputSchema,SpatialiteIndexOutputSchema,SpatialiteAnalyzeOutputSchema,SpatialiteTransformOutputSchema,SpatialiteImportOutputSchema) and wired them into all 7 SpatiaLite tool definitions — these were the only tool group without output schema enforcement. - Inline Schema Consolidation: Replaced 5 inline
z.object()output schemas with named imports fromoutput-schemas/—sqlite_fuzzy_match,sqlite_phonetic_match,sqlite_text_normalize,sqlite_stats_regression,sqlite_stats_outliers. Updated the corresponding named schemas (FuzzySearchOutputSchema,SoundexOutputSchema,TextNormalizeOutputSchema,StatsRegressionOutputSchema,StatsOutliersOutputSchema) to match actual handler return shapes. - Dead Schema Removal: Deleted 25 orphaned output schemas that had no corresponding tools: 9 vector (
VectorCreate,VectorInsert,VectorUpsert,CosineSimilarity,EuclideanDistance,DotProduct,VectorMagnitude,HybridSearch+ result), 3 stats (StatsDescribe,StatsMode,StatsMedian), 3 virtual (GenerateDates,CteRecursive,PivotTable), 3 geo (GeoNearest+ result,GeoPolygonContains,GeoEncode), 2 text (Levenshtein,TrigramSimilarity), 2 JSON (JsonTree,JsonPatch), 1 FTS (FtsOptimize), 3 server (ServerInfo,ServerHealth,ListAdapters— built-in tools usecontentpattern, notstructuredContent). - API Consistency: Renamed
valueColumn→columninRunningTotalSchemaandMovingAverageSchemainput schemas (and all handler references) for consistency with the other 4 window function tools which all usecolumn. Updated unit tests accordingly. - Input Coercion: Added case-insensitive coercion to
TextNormalizeSchema.mode— uppercase values like"NFC"now coerce to"nfc"instead of failing Zod enum validation. - Payload Optimization: Changed
sqlite_list_tablesandsqlite_get_indexesdefaults forexcludeSystemTables/excludeSystemIndexesfromfalsetotrue— SpatiaLite system tables (27 entries) and system indexes (4 entries) are now excluded by default, reducinglist_tablesfrom 38→11 entries andget_indexesfrom 8→4 entries. PassexcludeSystemTables: false/excludeSystemIndexes: falseto restore the previous behavior. - Validation Leak: Added missing
try/catcharoundListTablesSchema.parse()insqlite_list_tableshandler — the only core tool handler without the defensive wrapper. Zod parse errors now return structured{success: false}responses instead of propagating as uncaught exceptions. - Payload Optimization: Filtered internal
_mcp_migrationstable fromsqlite_list_tablesdefault results — the db-mcp migration tracking table is now excluded alongside SpatiaLite system tables whenexcludeSystemTables: true(default). Tables prefixed with_mcp_are internal and not relevant to user workflows. - API Consistency: Renamed
tableName→tablein core tool input schemas (sqlite_create_table,sqlite_describe_table,sqlite_drop_table,sqlite_get_indexes,sqlite_create_index) to match the field naming convention used by all other tool groups (json, text, stats, vector, admin). - Backward Compatibility: Added
resolveAliases()parameter alias support to all 8 core tool handlers and 2 window function handlers — legacy parameter names (tableName,sql,name,valueColumn) are transparently mapped to canonical names (table,query,indexName,column) before Zod parsing. Canonical names take precedence when both are supplied. Applied via handler-level preprocess (not schema-levelz.preprocess()which would break the SDK's.partial()call). Also changedregisterToolImplto use.partial().passthrough()so unknown alias keys survive Zod's default strip mode. - Stale References: Fixed
sqlite://help/statsreferencingvalueColumninstead ofcolumninrunning_totalandmoving_avgexamples (bothstats.mdsource and compiledserver-instructions.ts). Fixed codemodePOSITIONAL_PARAM_MAPandGROUP_EXAMPLESstill usingtableNamefor core tools after the rename totable. - Raw MCP Error: Fixed
sqlite_create_tablepropagating a raw MCP error whenifNotExists: falseand the table already exists —adapter.executeQuery()was outside anytry/catch, so the SQLite error escaped as an uncaught exception instead of returning a structured{success: false}response. - Error Quality: Added
sqlite_mastertable existence validation andpragma_table_infocolumn existence validation to all 6 window function tools (sqlite_window_row_number,sqlite_window_rank,sqlite_window_lag_lead,sqlite_window_running_total,sqlite_window_moving_avg,sqlite_window_ntile) — previously relied on SQL execution errors which leaked raw SQL in the errordetailsfield. Now returns cleanTABLE_NOT_FOUND/COLUMN_NOT_FOUNDstructured errors consistent with all other tool groups. - Chi-Square Validation: Fixed
sqlite_stats_hypothesiswithtestType: "chi_square"incorrectly rejecting non-numeric columns — thevalidateNumericColumn()check ran unconditionally for all test types before branching, but chi-square tests operate on categorical data. Numeric validation now only runs forttest_oneandttest_two. - OrderBy Validation: Added
validateOrderByColumns()pre-validation to all 6 window function tools — parses column names from ORDER BY expressions (handlingprice DESC, multi-columna, b DESC, and expression skipping), then validates each against the table schema. Previously, nonexistent orderBy columns produced raw SQL errors with internal query leakage indetails.sql. - Test Prompt: Fixed
test-group-tools.mdchecklist item 19 missing requireddirection: "lag"parameter forsqlite_window_lag_lead. - Output Schema Alignment: Added missing
messagefield toVectorBatchStoreOutputSchema— handler returnsmessage: "No items provided"on empty-items path but the output schema did not declare it. - Dimension Validation: Fixed
sqlite_vector_storeandsqlite_vector_batch_storesilently accepting mismatched vector dimensions when the table lacks adimensionscolumn (e.g., tables not created viasqlite_vector_create_table). Added a third fallback tovalidateDimensions()that samples an existing vector from the actual vector column to infer expected dimensions. - Inline Schema Consolidation: Relocated
AppendInsightOutputSchemafrom handler helpers (tools/admin/helpers.ts) to the centralizedoutput-schemas/admin.ts— consistent with the project convention that all output schemas live in theoutput-schemas/directory with named exports. - Output Schema Wiring: Created
DbstatOutputSchema(polymorphic — supports summarized, raw, and fallback return shapes) and wired it to thesqlite_dbstattool definition — the only admin tool without output schema enforcement. - Output Schema Alignment: Fixed
sqlite_list_viewserror path returning bareformatHandlerError(error)without required output schema fields (count,views) — now merges{count: 0, views: []}to passListViewsOutputSchemavalidation on error paths. - Output Schema Alignment: Added missing
skippedandwarningfields toVectorSearchOutputSchema— handler returns these fields when unparseable vectors are encountered during search, but the output schema did not declare them, causing raw MCP-32602errors on direct tool calls that trigger the skip path. - Missing Annotations: Added MCP annotations to all 7 SpatiaLite tools (
spatialite_load,spatialite_create_table,spatialite_query,spatialite_index,spatialite_analyze,spatialite_transform,spatialite_import) — these were the only tools withoutannotations, causing the code mode readonly guard to classify write tools as read-safe. - Readonly Guard: Fixed code mode
isWriteTool()using fail-open logic (readOnlyHint !== false) that treated unannotated tools as read-safe. Inverted to fail-closed (readOnlyHint === true) — tools are now assumed to be write tools unless explicitly marked as read-only. Removed redundantREAD_SAFE_PATTERNSheuristic. Added defense-in-depth warning logging for any unannotated tool blocked in readonly mode. - Validation Leak: Fixed
sqlite_text_case,sqlite_text_normalize, andsqlite_text_validateproducing raw MCP-32602errors when required enum params (mode,pattern) receive empty or invalid values. Replacedz.enum()in schemas withz.string()and handler-side validation against exported const arrays (VALID_TEXT_CASE_MODES,VALID_NORMALIZE_MODES,VALID_VALIDATE_PATTERNS). Fixedsqlite_phonetic_matchalgorithmparam leaking on explicit empty string by adding a preprocess coercer. - Output Schema Wiring: Created 4 new text output schemas (
TextConcatOutputSchema,TextTrimOutputSchema,TextCaseOutputSchema,TextSubstringOutputSchema) and wired them to their tool definitions. Relocated inlineAdvancedSearchOutputSchemafromsearch.tsto centralizedoutput-schemas/text.ts. - Validation Leak: Fixed
sqlite_stats_group_byandsqlite_stats_hypothesisproducing raw MCP-32602errors when required enum params (stat,testType) receive empty or invalid values. Replacedz.enum()in schemas withz.string()and handler-side validation against exported const arrays (VALID_STAT_TYPES,VALID_TEST_TYPES). - Enum Coercion: Added
z.preprocess(coerceEnum, ...)to 6 optionalz.enum()params that leaked raw MCP-32602on explicit empty strings:orderByandstatinGroupByStatsSchema,orderDirectioninTopNSchema,methodinOutlierSchema,modeinTextTrimSchema,tokenizerinFtsCreateSchema,formatinFtsMatchInfoSchema. Empty strings now coerce toundefinedso.default()kicks in. - Validation Leak: Fixed
sqlite_text_trimandsqlite_phonetic_matchproducing raw MCP-32602errors when optional enum params (mode,algorithm) receive invalid non-empty values. Replacedz.enum()in schemas withz.string()and handler-side validation against exported const arrays (VALID_TRIM_MODES,VALID_PHONETIC_ALGORITHMS), consistent with the pattern used bytext_case,text_normalize, andtext_validate. - Enum Coercion: Replaced
coerceEnum(empty-string-only) withcoerceEnumValuesfactory for 5 optionalz.enum()params with defaults —orderByinGroupByStatsSchema,orderDirectioninTopNSchema,methodinOutlierSchema,tokenizerinFtsCreateSchema,formatinFtsMatchInfoSchema. Invalid non-empty strings (e.g.,"invalid","abc") now coerce toundefinedso.default()kicks in, instead of leaking raw MCP-32602from the innerz.enum()rejection. - Validation Leak: Fixed
sqlite_advanced_searchtechniquesarray parameter producing a raw MCP-32602error when array elements contain invalid enum values (e.g.,["invalid_technique"]). Replacedz.enum(["exact", "fuzzy", "phonetic"])inside the array withz.string()and handler-side validation against exportedVALID_SEARCH_TECHNIQUESconstant, consistent with the pattern used by all other enum params in text tools. - Payload Optimization:
sqlite_stats_top_nnow auto-excludes long-content TEXT/BLOB columns (matching names likedescription,body,notes,content,summary, etc.) whenselectColumnsis not specified. Short identifier columns (name,category,email, etc.) are preserved. Ahintfield in the response lists excluded columns. UseselectColumnsto override and include specific text columns. - Misleading Stats: Fixed
sqlite_stats_summaryreturning misleadingavg: 0with nullmin/maxwhen the user explicitly requests text columns via thecolumnsparameter. Now returns{column, error: "Not numeric"}per-column (using the existing error field in the summary schema) instead of running SQL aggregates that produce meaningless results on text data. - Code Mode Alias: Changed
sqlite.stats.describe()alias mapping fromstatsBasic→statsSummary— callingdescribe({table: 'foo'})now returns a table-level summary of all numeric columns, matching the intuitive expectation of "describe a table" rather than requiring acolumnparameter. - Error Field Consistency: Fixed
sqlite_create_csv_tableusingmessageinstead oferrorfor failure text in two early-return paths (relative path rejection and WASM/CSV unavailability) — now consistent with the structured error convention used by all other tools. - Raw MCP Error: Fixed
sqlite_vacuumwithintoparameter propagating a raw MCP error instead of a structured response. Added early WASM guard forVACUUM INTO(file system access not supported in WASM mode) and wrappedexecuteQuery()intry/catchso SQL failures (e.g., invalid target paths) return structured{success: false}responses. AddedwasmLimitationfield toVacuumOutputSchema. - Input Coercion: Fixed required numeric parameters in geo tools (
lat1,lon1,lat2,lon2,centerLat,centerLon,radius,minLat,maxLat,minLon,maxLon) producing raw MCP-32602errors when receiving wrong-type string inputs (e.g.,"abc"). Changed schema inner types from requiredz.number()toz.number().optional()socoerceNumber'sundefinedfallback passes the SDK boundary, then addedrequireCoordinate()andrequireNumber()handler-level validators that return structured{success: false}errors withGEO_INVALID_COORDINATEScode. - Misleading Suggestion: Fixed
sqlite_query_planclassifyingSCAN CONSTANT ROWas a full table scan on synthetic table "CONSTANT" and suggesting adding an index — constant-row, subquery, list, and materialized EXPLAIN plan entries are now excluded from fullScans/indexScans/coveringIndexes lists and optimization suggestions. - Validation Leak: Fixed
sqlite_window_rankandsqlite_window_lag_leadproducing raw MCP-32602errors when enum params (rankType,direction) receive invalid values.rankType(optional with default) now usescoerceEnumValuescoercer so invalid values fall to the"rank"default.direction(required, no default) changed fromz.enum()toz.string()with handler-side validation againstVALID_DIRECTIONSconstant, returning a structured error. - Error Quality: Added table existence pre-validation to
sqlite_fts_search,sqlite_fts_rebuild, andsqlite_fts_match_info— previously, querying a nonexistent FTS table produced a genericDB_QUERY_FAILEDerror with leaked SQL. Now returns a cleanTABLE_NOT_FOUNDstructured error consistent with all other text group tools. Extracted reusablevalidateTableExists()fromcolumn-validation.ts. - Case Sensitivity: Fixed
sqlite_window_lag_leadrejecting uppercase"LAG"/"LEAD"direction values despite the schema description suggesting them. The handler now normalizes direction to lowercase before validation, so"LAG","lag", and"Lag"are all accepted. - Error Code Refinement: Fixed
DbMcpErrorsubclasses (e.g.,QueryError) always using their generic constructor code (e.g.,DB_QUERY_FAILED) even when the error message matches a more specific suggestion pattern (e.g.,TABLE_NOT_FOUND,COLUMN_NOT_FOUND). The constructor now auto-refines generic codes (DB_QUERY_FAILED,DB_WRITE_FAILED,QUERY_ERROR,RESOURCE_ERROR,UNKNOWN_ERROR) to the suggestion's specific code when available. This fixes all vector, stats, and other tools that delegate toexecuteReadQuery/executeWriteQuery— they now returnTABLE_NOT_FOUNDinstead ofDB_QUERY_FAILEDfor missing tables. - Error Code Consistency: Added missing
code: "DIMENSION_MISMATCH"tosqlite_vector_distancedimension mismatch error —sqlite_vector_storeandsqlite_vector_batch_storealready return this code, butvector_distancereturned a bare{success: false, error: "..."}without it. - Error Code Consistency: Added missing
code: "VECTOR_NOT_FOUND"tosqlite_vector_getnot-found error — both{success: false}return paths now include a specific error code for programmatic handling. - Error Code Refinement: Added
VIEW_NOT_FOUNDandFILE_NOT_FOUNDerror suggestion patterns —sqlite_drop_viewon a nonexistent view andsqlite_create_csv_tableon a nonexistent file now return specific codes instead of genericDB_WRITE_FAILED. Both patterns also provide actionable suggestions. - Error Field Consistency: Added missing
code: "VALIDATION_ERROR"andcategory: "validation"tosqlite_create_csv_tableandsqlite_analyze_csv_schemarelative path rejection responses — previously returned bare{success: false, error: "..."}without structured error metadata. - Error Code Consistency: Added missing error codes to 5 admin tool error responses:
sqlite_pragma_table_info(TABLE_NOT_FOUND),sqlite_pragma_settings(VALIDATION_ERRORfor invalid/unknown pragma names),sqlite_verify_backup(FILE_NOT_FOUNDfor missing files,VALIDATION_ERRORfor empty paths,ATTACH_FAILEDfor attach errors),sqlite_virtual_table_info(TABLE_NOT_FOUND). Addederrorfield andVALIDATION_ERRORcode tosqlite_drop_virtual_tablewhen attempting to drop a regular table (previously usedmessagefield only). - Error Code Consistency: Fixed
sqlite_transaction_executefailure response missing structured error metadata (code,category,suggestion,recoverable) — now usesformatHandlerError()and spreads the formatted error, so failures return specific codes likeTABLE_NOT_FOUNDinstead of bare{success: false, error: "..."}. - Error Suggestion: Added
TRANSACTION_CONFLICTerror suggestion pattern for "cannot start a transaction within a transaction" errors — advises committing/rolling back the active transaction or usingsqlite_transaction_executefor atomic multi-statement operations. - Graph Semantics: Fixed
sqlite_dependency_graphrootTablesandleafTablesoverlapping for tables with no FK relationships. Root now means "referenced by others but doesn't reference anything" and leaf means "references others but isn't referenced by anything." Isolated tables (no FK relationships at all) are excluded from both, making the sets properly disjoint. - Error Code Consistency: Added missing
code: "TABLE_NOT_FOUND"and structured error metadata tosqlite_constraint_analysisandsqlite_cascade_simulatornonexistent table responses — previously returned bare{success: false, error: "..."}without error codes. - Error Code Consistency: Added missing
code: "VALIDATION_ERROR"and structured error metadata tosqlite_query_plannon-SELECT rejection response — previously returned bare{success: false, error: "..."}without error codes. - FK Awareness: Enhanced
sqlite_migration_risksDROP TABLE analysis to check for FK dependents — when a table that other tables reference via foreign keys is dropped, the risk description now lists the dependent tables and the mitigation suggests handling them first. - Limit After Filter: Fixed
sqlite_storage_analysislimitparameter being applied at the SQL level before SpatiaLite system table filtering —limit: 3withexcludeSystemTables: truecould return fewer tables than requested because system tables consumed slots in the SQL result set before being filtered out. Limit is now applied via.slice()after filtering in both thedbstatand fallback code paths. - Error Code Consistency: Added missing structured error codes to all migration tool error responses:
sqlite_migration_apply(DUPLICATE_MIGRATION,MIGRATION_NOT_INITIALIZED,MIGRATION_EXECUTION_FAILED),sqlite_migration_record(DUPLICATE_MIGRATION,MIGRATION_NOT_INITIALIZED),sqlite_migration_rollback(VALIDATION_ERROR,MIGRATION_NOT_FOUND,ROLLBACK_SQL_MISSING,MIGRATION_NOT_INITIALIZED),sqlite_migration_history(MIGRATION_NOT_INITIALIZED) — previously returned bare{success: false, error: "..."}without error codes for programmatic handling. - Migration Status Semantics:
sqlite_migration_recordnow inserts withstatus: 'recorded'instead of'applied'— distinguishes externally-recorded migrations from those actually executed bysqlite_migration_apply. Addedrecordedcount tosqlite_migration_statusoutput. Status output schema updated to include the new count field. - Rollback Safety:
sqlite_migration_rollbacknow rejects re-rolling back an alreadyrolled_backmigration withALREADY_ROLLED_BACKerror code — previously would silently re-execute the rollback SQL, which could cause errors for non-idempotent rollback statements. - Duplicate Version Blocking:
sqlite_migration_recordandsqlite_migration_applynow reject duplicate version identifiers withDUPLICATE_VERSIONerror code — previouslymigrationRecordonly warned andmigrationApplyhad no version check at all. Duplicate versions caused ambiguity withmigrationRollbackwhich looks up by version and would silently target only the latest record. - Rollback SQL Validation:
sqlite_migration_rollbacknow detects comment-only rollback SQL (e.g.,"-- Cannot drop column") and returnsROLLBACK_SQL_INVALIDerror — previously attempted to execute the comments, producing a confusingDB_WRITE_FAILEDerror with"The supplied SQL string contains no statements". Strips single-line (--) and multi-line (/* */) comments before checking for executable content. - Migration Dedup Scope: Fixed
sqlite_migration_applySHA-256 dedup check blocking therecord → applyworkflow — the dedup previously matched against ALL migration statuses, so recording a migration withmigrationRecordthen applying the same SQL withmigrationApplywas rejected as a duplicate. Dedup now only blocks againstappliedmigrations, allowing: (1)recordthenapplywith the same SQL, (2) re-apply after rollback. Also fixed post-insert SELECT in bothapply.tsandrecord.tsfetching bymigration_hash(returns wrong row when multiple rows share a hash) — now fetches byversion(unique). - History Filter Completeness: Added
"recorded"toMigrationHistorySchema.statusenum — previously only["applied", "rolled_back", "failed"]were available, making it impossible to filter history byrecordedstatus. - Rollback on Recorded-Only Migrations:
sqlite_migration_rollbacknow handlesrecorded-only migrations (never applied) by marking them asrolled_backwithout executing rollback SQL — previously would blindly execute the rollback SQL even though the migration was never applied, which could cause errors or unintended side effects. Returnswarningexplaining the behavior. - Error Suggestion: Added
MALFORMED_JSONerror suggestion pattern for"malformed JSON"errors — commonly triggered whenjson_extract()receives a nonexistent column name (SQLite treats the unresolved identifier as a string literal and attempts to parse it as JSON). The suggestion now guides the agent to verify the column exists withsqlite_describe_table, instead of returning a genericDB_QUERY_FAILEDwith no guidance. - Error Field Consistency: Added missing
code: "VALIDATION_ERROR"andcategory: "validation"to WASM limitation error responses insqlite_verify_backup,sqlite_create_rtree_table,sqlite_create_csv_table, andsqlite_analyze_csv_schema— previously returned bare{success: false, error: "...", wasmLimitation: true}without structured error metadata, inconsistent withsqlite_backupandsqlite_restorewhich usedformatHandlerError(new ValidationError(...)). - Code Quality Audit — Magic JSON-RPC Error Code — Replaced 4 remaining inline
-32000literals withJSONRPC_SERVER_ERRORconstant insession.ts - Code Quality Audit — Removed unused deprecated
SERVER_INSTRUCTIONSexport fromserver-instructions.ts(zero consumers) - Code Quality Audit —
executeGeneral()inquery-executor.tsnow throwsQueryErrorwith logging (was bareError) - Code Quality Audit —
validateQuery()indatabase-adapter.tsnow throwsValidationErrorinstead of bareError - Code Quality Audit —
ensureConnected()/ensureDb()in both adapters now throwConnectionErrorinstead of bareError - Transport Feature Backport — Changed
Referrer-Policyfromstrict-origin-when-cross-origintono-referrer(API server has no referrer to share) - Version SSoT Mismatch — Synced hardcoded
0.1.0to1.0.2(matchingpackage.json) inindex.ts,McpServer.ts, andcli.ts - Duplicate Error Class Hierarchy — Removed 6 duplicate error classes from
types/index.ts(simple constructor) and consolidated intoutils/errors.ts(enhanced: category, suggestions, recoverable,toResponse());types/index.tsnow re-exports fromutils/errors.ts;auth/errors.tsupdated to extend enhancedDbMcpError; addedAUTHENTICATION/AUTHORIZATIONtoErrorCategoryenum - Bare
z.object({})Schemas — Added.strict()to 5 schemas (transaction_commit,transaction_rollback,MigrationInitSchema,MigrationStatusSchema,pragma_database_list) to reject extraneous properties sqlite_migration_risksDROP INDEX Detection — Now returnsmediumrisk forDROP INDEXstatements- Previously no risk entry was generated for
DROP INDEX(fell through all pattern checks) - Now detects
DROP INDEXwithriskLevel: "medium",category: "index_removal", and actionable mitigation advice
- Previously no risk entry was generated for
ERROR_SUGGESTIONSInsufficient Data Pattern — Regression tool's "Insufficient data" error now returnsVALIDATION_ERRORinstead ofUNKNOWN_ERRORsqlite_stats_regressionthrowsError("Insufficient data for degree N regression")when data points < degree+1- Message didn't match any
ERROR_SUGGESTIONSpattern and fell through toErrorCategory.INTERNAL→UNKNOWN_ERROR - Added
/insufficient data/ipattern mapping toErrorCategory.VALIDATIONwith actionable suggestion
sqlite_json_set/sqlite_json_removeNo-Match Warning — Returnswarningfield whenrowsAffected: 0- Previously returned
{success: true, rowsAffected: 0}with no indication that nothing was changed - Now includes
warning: "No rows matched the WHERE clause — no changes were made" - Mirrors the same pattern already applied to
sqlite_json_updateandsqlite_json_merge
- Previously returned
ERROR_SUGGESTIONSColumn Name Pattern Coverage — Addedhas no column namedpattern for INSERT/UPDATE column errors- SQLite uses "has no column named X" for INSERT/UPDATE column errors, distinct from "no such column" used by SELECT
- Previously classified as
UNKNOWN_ERROR(no pattern match); now returnsRESOURCE_ERRORwith actionable suggestion
sqlite_text_validateMissingcustomPatternError Code — Now returnsVALIDATION_ERRORinstead ofUNKNOWN_ERROR- Handler threw generic
Errorfor missingcustomPatternwhenpattern='custom';formatError()classified it asUNKNOWN_ERROR - Changed to throw
ValidationErrorwith properVALIDATION_ERRORcode andvalidationcategory
- Handler threw generic
sqlite_vector_store/sqlite_vector_batch_storeDDL-Based Dimension Check — Dimension validation now reads table schema DDL as primary source- Previously read
dimensionsfrom existing rows only — bypassed on empty tables or tables with mismatched row data - Now parses
DEFAULT NfromCREATE TABLESQL viasqlite_masterfor authoritative validation - Falls back to existing row data when DDL lacks a DEFAULT clause
- INSERT now explicitly sets
dimensionscolumn to actual vector length
- Previously read
sqlite_vector_searchSkipped Vector Reporting — Response now includesskippedcount andwarningwhen vectors fail similarity calculation- Previously, vectors with dimension mismatches or parse errors were silently dropped (try/catch returned null)
- Now surfaces a
warning: "N vector(s) skipped due to dimension mismatch or parse errors"field in the response - Helps callers diagnose why
countmay be less than expected
sqlite_json_update/sqlite_json_mergeNo-Match Warning — Returnswarningfield whenrowsAffected: 0- Now includes
warning: "No rows matched the WHERE clause — nothing was updated/merged" - Helps callers distinguish between a successful no-op and an actual problem
- Now includes
sqlite_stats_histogramEmpty Table Phantom Bucket — Histogram on empty table no longer returns a phantom{min: 0, max: 0, count: 1}bucket- Root cause:
MIN()/MAX()return NULL on empty tables, which defaulted to 0 via?? 0, makingbucketSize === 0and returning a hardcodedcount: 1 - Now counts non-null rows via
COUNT(column)and returns emptybuckets: []when no data exists - Uniform data (all values identical) now returns actual row count instead of hardcoded 1
- Root cause:
sqlite_vector_store/sqlite_vector_batch_storeDimension Mismatch Validation — Storing vectors with wrong dimensions now returns a structured error- Previously accepted any vector length regardless of table's configured
dimensionscolumn (e.g., storing 2-dim vector in 4-dim table succeeded silently) - Now reads the table's
dimensionscolumn and returns{success: false, code: "DIMENSION_MISMATCH"}when vector length doesn't match sqlite_vector_searchalready validated dimensions at comparison time (via helper functions), so this adds write-side enforcement
- Previously accepted any vector length regardless of table's configured
- Introspection Tools WASM FTS5 Crash — 5 introspection tools no longer crash when the database contains FTS5 virtual tables in WASM mode
sqlite_dependency_graph,sqlite_topological_sort,sqlite_cascade_simulator,sqlite_schema_snapshot,sqlite_constraint_analysisall failed with "no such module: fts5" because internal queries (SELECT COUNT(*),PRAGMA table_info,PRAGMA foreign_key_list) hit FTS5 virtual tables that WASM SQLite can't resolve- Added try/catch around per-table queries in
buildForeignKeyGraph()(graph.ts) andschemaSnapshot/constraintAnalysishandlers (analysis.ts) - FTS5 tables are still included in results (with rowCount 0 and columnCount 0) but no longer crash the entire operation
sqlite_json_normalize_columnWASM Compatibility — Fixed all rows silently failing in WASM mode- Root cause:
SELECT rowid, ...doesn't exposerowidas a named column in sql-js when the table has an INTEGER PRIMARY KEY - Handler received
undefinedforrow["rowid"], causing all per-row UPDATE queries to fail in the inner try/catch - Fix: Changed to
SELECT _rowid_ AS _rid_which SQLite guarantees to work across all backends - Added
firstErrorDetailfield to response when errors occur, making per-row failures diagnosable without reading source code
- Root cause:
- Security Test Assertion Migration — Updated 11 tests from
.rejects.toThrow()to structured error assertionspragma-security.test.ts: 3sqlite_pragma_table_infoinjection tests now assert{success: false, error: /invalid/i}identifier-integration.test.ts: 6 FTS tool injection tests and 2 admin tool injection tests (pragma_table_info,index_stats) updated- These tests were stale after handlers were migrated to return structured
{success: false}instead of throwing
sqlite_index_statsStructured Error Handling — Handler now wrapped in try/catch withformatError()sanitizeIdentifier()andSchema.parse()were outside any try/catch, causing rawInvalidIdentifierErrorthrows- Now returns
{success: false, indexes: [], error: "Invalid identifier..."}consistent with all other admin tools
- FTS Security Test Assertion Migration — Updated 7 FTS injection tests from
.rejects.toThrow()to structured error assertionsfts-injection.test.ts: 4sqlite_fts_create, 1sqlite_fts_search, 1sqlite_fts_rebuild, 1sqlite_fts_match_infoinjection tests updated
- Core Query Tool Validation Hardening —
sqlite_read_queryandsqlite_write_queryhandlers now catch Zod validation errors as structured{success: false}responses- Wrapped
Schema.parse(params)inside try/catch blocks in bothcreateReadQueryToolandcreateWriteQueryToolhandlers sqlite_read_query: Added empty query guard — empty string""previously returned{success: true, rowCount: 0}instead of a validation error- Now returns
{success: false, error: "Query cannot be empty. Provide a valid SELECT, PRAGMA, EXPLAIN, or WITH statement."}
- Wrapped
- Text/FTS Tool Zod Validation Error Handling — All 17 text and FTS tool handlers now catch Zod validation errors as structured
{success: false}responses- 13 text tools (
regex.ts,formatting.ts,search.ts): MovedSchema.parse(params)inside try/catch blocks withformatError() - 4 FTS tools (
fts.ts): MovedSchema.parse(params)plus FTS5 availability checks and identifier validation inside try/catch blocks - Previously, calling these tools with invalid parameters returned raw MCP error frames instead of structured handler errors
- 13 text tools (
- Introspection Tool Zod Validation Error Handling — All 9 introspection tool handlers now catch Zod validation errors as structured
{success: false}responsessqlite_dependency_graph,sqlite_topological_sort,sqlite_cascade_simulator,sqlite_schema_snapshot,sqlite_constraint_analysis,sqlite_migration_risks,sqlite_storage_analysis,sqlite_index_audit,sqlite_query_plan: MovedSchema.parse(params)inside try/catch blocks withformatError()- Previously, calling tools with invalid parameters (wrong types, missing required fields, out-of-range values) returned raw MCP error frames instead of structured handler errors
sqlite_query_planmin(1) Refinement Leak — Removed.min(1)fromQueryPlanSchema.sqland added handler-level validation.partial()inDatabaseAdapter.registerTool()makes keys optional for SDK validation, but doesn't strip refinements likemin(1)- When
sql: ""was passed, themin(1)check fired at the SDK level, producing raw MCP error -32602 - Now validates empty
sqlinside the handler and returns structured{success: false, error: "Parameter 'sql' is required..."}
- Geo Tool Zod Validation Error Handling — All 4 Haversine geo tool handlers now catch Zod validation errors as structured
{success: false}responsessqlite_geo_distance,sqlite_geo_nearby,sqlite_geo_bounding_box,sqlite_geo_cluster: MovedSchema.parse(params)inside try/catch blocks withformatError()- Previously, calling these tools with empty or invalid parameters returned raw MCP error frames instead of structured handler errors
- Geo Tool Coordinate Range Validation — Moved
.min(-90).max(90)/.min(-180).max(180)refinements from Zod schemas to handler-level validationsqlite_geo_distance: lat1, lon1, lat2, lon2 range validation viavalidateCoordinates()helpersqlite_geo_nearby: centerLat, centerLon range validationsqlite_geo_bounding_box: minLat, maxLat, minLon, maxLon range validation- Previously, out-of-range coordinates (e.g.,
lat1: 91) triggered raw MCP-32602errors at the SDK boundary before the handler ran - Now returns structured
{success: false, error: "Invalid lat1: 91. Must be between -90 and 90."}
- Admin Tool Zod Validation Error Handling — 11 admin tool handlers now catch Zod/sanitizeIdentifier errors as structured
{success: false}responsessqlite_pragma_table_info,sqlite_virtual_table_info,sqlite_create_csv_table,sqlite_create_rtree_table,sqlite_create_series_table,sqlite_append_insight: Added try/catch aroundSchema.parse(params)andsanitizeIdentifier()callssqlite_backup,sqlite_restore,sqlite_generate_series,sqlite_analyze_csv_schema,sqlite_transaction_execute: Added try/catch aroundSchema.parse(params)callsAppendInsightSchema.insightnow requires.min(1)to reject empty strings (previously accepted""silently)
- Migration Tool Zod Validation Error Handling —
sqlite_migration_recordandsqlite_migration_applyhandlers now catch Zod validation errors as structured{success: false}responses- Moved
Schema.parse(params)inside existing try/catch blocks intracking.ts - Previously, calling these tools with empty
{}params returned raw MCP error frames instead of structured handler errors
- Moved
- Code Mode
logAlias Mapping — Fixedsqlite.migration.log()pointing tomigrationRecordinstead ofmigrationHistorylogsemantically means "show the log of migrations", not "record a new migration"- Calling
sqlite.migration.log()previously requiredversionandmigrationSqlparams (record) — now correctly returns migration history with no required params
- JSON Tool Zod Validation Error Handling — All 23 JSON tool handlers now catch Zod validation errors as structured
{success: false}responses- Previously, calling any JSON tool with empty or invalid parameters returned raw MCP error
-32602instead of a structured handler error - Root cause: MCP SDK validates
inputSchemaat the transport layer before the handler runs, rejecting required-field violations as-32602 - Fix:
DatabaseAdapter.registerTool()now wraps inputSchema with.partial()so the SDK accepts any param subset; handler-levelSchema.parse()validates strictly and returns structured errors viaformatError() - Added try/catch around
Schema.parse(params)in all 23 JSON handlers across 4 files:crud.ts(7),query.ts(4),transform.ts(4),json-helpers.ts(8)
- Previously, calling any JSON tool with empty or invalid parameters returned raw MCP error
- Core Table Tool Zod Validation Error Handling — 3 table handlers (
sqlite_create_table,sqlite_describe_table,sqlite_drop_table) now catch Zod validation errors as structured{success: false}responses- Previously, calling these tools with missing required parameters (e.g., empty
{}) threw raw MCP errors instead of returning structured handler errors - Added try/catch around
Schema.parse(params)in all 3 handlers intables.tswithformatError()for consistent error responses
- Previously, calling these tools with missing required parameters (e.g., empty
- Index Tool Zod Validation Error Handling — All 3 index handlers (
sqlite_get_indexes,sqlite_create_index,sqlite_drop_index) now catch Zod validation errors as structured{success: false}responses- Root cause:
CreateIndexSchema.columnshad.min(1)which the MCP SDK validates before the handler runs, surfacing as raw MCP error-32602 - Moved
min(1)check to handler-level validation returning{success: false, message: "At least one column is required..."} - Wrapped all
Schema.parse()calls in try/catch blocks withformatError()for defense-in-depth
- Root cause:
- Multi-Session Streamable HTTP Crash — Fixed
Already connected to a transporterror when creating 2+ concurrent sessions- SDK's
McpServer.connect()only supports one active transport; secondconnect()threw - Added close-before-reconnect pattern wrapping
server.connect()in try-catch
- SDK's
sqlite_spatialite_indexCheck Returnsvalid: falsefor Valid Indexes — Now treatsCheckSpatialIndexnull result as indeterminate- SpatiaLite 5.x's
CheckSpatialIndex()commonly returnsnullinstead of1for valid indexes - Previously interpreted
nullasfalse, producing misleading message "Spatial index exists but may be invalid" - Now returns
valid: nullwith message "Spatial index exists (validation inconclusive — common in SpatiaLite 5.x)" - Explicit
valid: falsenow only shown whenCheckSpatialIndexreturns0(actually invalid index)
- SpatiaLite 5.x's
sqlite_spatialite_create_tableMisleading Success on Existing Table — Now returnsalreadyExists: truewhen table already exists- Previously used
CREATE TABLE IF NOT EXISTSand always reported"Spatial table 'X' created"even when table already existed - Now pre-checks table existence and returns accurate message:
"Spatial table 'X' already exists"withalreadyExists: trueflag - Prevents confusion about whether data was reset or preserved
- Previously used
sqlite_spatialite_indexCreate/Drop/Check Idempotency — All 3 index actions now report accurate statecreate: ReturnsalreadyExists: truewhen index already exists instead of silently runningCreateSpatialIndexagaindrop: ReturnsalreadyDropped: truewhen no index exists instead of misleadingly reporting"Spatial index dropped"check: Returns{ indexed: false }when no index exists, or{ indexed: true, valid: true/false }when index exists — previously returned raw{ result: [{ "CheckSpatialIndex(...)": null }] }- Index existence checked via
idx_{table}_{column}insqlite_master
sqlite_spatialite_analyzeDistance MatrixtargetTableSupport — Now usestargetTableparameter when provided- Previously, the
distance_matrixanalysis type always usedsourceTablefor both sides of the cross-join, ignoringtargetTable - Now uses
targetTable(defaulting tosourceTablewhen omitted) and only appliesa.id < b.iddedup filter for same-table queries
- Previously, the
- SpatiaLite Tool Structured Error Responses — All 7 SpatiaLite handlers now return structured errors instead of throwing raw MCP exceptions
- Added
formatErrorimport and try/catch blocks to all 7 handlers:sqlite_spatialite_load,sqlite_spatialite_create_table,sqlite_spatialite_query,sqlite_spatialite_analyze,sqlite_spatialite_index,sqlite_spatialite_transform,sqlite_spatialite_import sqlite_spatialite_query: Nonexistent table errors now return{success: false, error, code, suggestion}instead of propagating as raw MCP exceptionssqlite_spatialite_analyze: Same fix — structured error response for nonexistent tables and invalid table namessqlite_spatialite_index: Added table existence validation — previously returned{success: true}for nonexistent tables; now returns{success: false, error: "Table 'x' does not exist"}sqlite_spatialite_transform: Added null-result validation — previously returned{success: true, result: null}for invalid WKT geometry; now returns{success: false, error: "Invalid geometry..."}sqlite_spatialite_import: Added WKT pre-validation viaGeomFromText()— previously silently accepted invalid WKT strings like"INVALID_WKT"; now returns{success: false, error: "Invalid WKT geometry..."}sqlite_spatialite_create_table: Validation errors (invalid table/column names) now return structured responses instead of throwing- Tests updated to expect structured error responses instead of catching thrown errors; 11 tests covering all 7 tools
- Previously threw raw MCP exception when called with a nonexistent table
- Now returns
{success: false, error, code, suggestion}consistent with all other tool groups - Security test updated to assert structured error response instead of
.rejects.toThrow()
- Added
sqlite_restoreRelative Path Resolution — Now resolves relative paths to absolute before file existence check- Previously used raw
input.sourcePathwithfs.existsSync, which resolved against the MCP server's CWD (e.g., Antigravity IDE directory) - Stale 0-byte files left by SQLite
ATTACH DATABASEat the server CWD could cause false-positive{success: true}responses - Now uses
nodePath.resolve()consistent with the existingsqlite_verify_backuphandler
- Previously used raw
sqlite_backupRelative Path Resolution — Now resolves relative paths to absolute beforeVACUUM INTO- Previously used raw
input.targetPathforVACUUM INTO, causing backups to be written to the MCP server's CWD instead of the expected location - Now uses
nodePath.resolve()consistent withsqlite_verify_backupandsqlite_restore
- Previously used raw
sqlite_drop_viewMisleading Success Message — Now reports "did not exist (no action taken)" for nonexistent views- Previously always returned
View 'x' droppedregardless of whether the view existed (whenifExists: true) - Now checks view existence before dropping, consistent with
sqlite_drop_virtual_tablepattern
- Previously always returned
sqlite_verify_backupRelative Path False Positive — Now resolves relative paths to absolute beforefs.existsSynccheck- Previously, relative paths like
"nonexistent_file.db"bypassed the file existence check (resolved against MCP server CWD, not database directory) andATTACH DATABASEsilently created an empty DB, returning{success: true, valid: true, pageCount: 0} - Now uses
nodePath.resolve()to convert to absolute path before checking, ensuring consistent behavior regardless of server CWD
- Previously, relative paths like
sqlite_pragma_settingsNonexistent PRAGMA Error Message — Returns user-friendly error for unknown PRAGMAs- Previously, querying a nonexistent PRAGMA like
nonexistent_pragma_xyzreturned the confusing better-sqlite3 internal error:"This statement does not return data. Use run() instead"withUNKNOWN_ERRORcode - Now detects this specific error pattern and returns
{success: false, error: "Unknown or write-only PRAGMA: 'nonexistent_pragma_xyz'"} inputparsing moved before try/catch block to ensure PRAGMA name is accessible in error handler
- Previously, querying a nonexistent PRAGMA like
sqlite_pragma_settingsStructured Error Response — Handler now wrapped in try/catch withformatError()- Previously, invalid PRAGMA names threw raw MCP exceptions instead of structured error responses
- Now returns
{success: false, error: "Invalid PRAGMA name"}for validation failures - Catches all SQLite errors and returns structured
{success: false, error, code, suggestion}responses
sqlite_verify_backupNonexistent File Validation — Now pre-validates file existence before ATTACH- Previously, ATTACH silently created an empty DB for nonexistent files, returning false-positive
{success: true, valid: true, pageCount: 0} - Now returns
{success: false, message: "Backup file not found: ..."}when file doesn't exist - Outer try/catch with
formatError()added for unexpected errors
- Previously, ATTACH silently created an empty DB for nonexistent files, returning false-positive
sqlite_restoreNonexistent File Validation — Now pre-validates source file existence before ATTACH- Previously, ATTACH silently created an empty DB for nonexistent files, returning false-positive
{success: true} - Now returns
{success: false, message: "Source file not found: ..."}when file doesn't exist
- Previously, ATTACH silently created an empty DB for nonexistent files, returning false-positive
- Transaction Tool Structured Error Responses — All 6 transaction handlers now return structured errors instead of throwing raw MCP exceptions
sqlite_transaction_begin,sqlite_transaction_commit,sqlite_transaction_rollback: Errors like double-begin and no-active-transaction now return{success: false, error, code, suggestion}instead of propagating as unhandled exceptionssqlite_transaction_savepoint,sqlite_transaction_release,sqlite_transaction_rollback_to: Invalid savepoint names return{success: false, error: "Invalid savepoint name"}instead of throwing; nonexistent savepoint errors return structured responses- Added
formatErrorimport totransactions.ts - Security tests updated to assert structured error responses instead of
.rejects.toThrow()
sqlite_vector_distanceMissing Error Handling — Handler now wrapped in try/catch withformatError()- Previously, Zod validation errors from malformed input threw raw MCP exceptions instead of structured error responses
- Now consistent with
sqlite_vector_normalizeand all other vector tool handlers
sqlite_vector_batch_storeEmpty Items Table Validation — Now validates table existence even when items array is empty- Previously,
batch_store({table: "nonexistent", items: []})returned{success: true, stored: 0}without checking if the table exists - Now queries
sqlite_masterto verify table existence before returning the empty-items early response - Returns
{success: false, error: "Table 'x' does not exist"}for nonexistent tables
- Previously,
sqlite_vector_getColumn Not Found Error — Provides clear error when vector column doesn't exist in row data- Previously returned misleading
"Invalid vector format"withUNKNOWN_ERRORcode when the specified vector column was not found in the row - Now returns descriptive error:
"Column 'x' not found or contains NULL. Available columns: ..."listing actual column names
- Previously returned misleading
sqlite_vector_countDimensions Filter —dimensionsparameter now filters results instead of being silently ignored- Previously
sqlite_vector_count({table: "t", dimensions: 8})returned total row count regardless of dimensions value - Now adds
WHERE dimensions = Nclause when dimensions parameter is specified
- Previously
sqlite_vector_normalizeError Handling — Handler now wrapped in try/catch withformatError()- Previously threw raw Zod validation errors instead of returning structured error responses
- Now consistent with all other vector tool handlers
sqlite_vector_batch_storeEmpty Items Validation — Returns early with{stored: 0, message: "No items provided"}for empty items array- Previously, empty items array on a nonexistent table silently returned
{success: true, stored: 0}without touching the database - Now short-circuits before any SQL execution, preventing misleading success responses
- Previously, empty items array on a nonexistent table silently returned
- Vector Tool Structured Error Responses — All 11 vector handlers now return structured errors instead of throwing raw MCP exceptions
sqlite_vector_create_table,sqlite_vector_store,sqlite_vector_batch_store,sqlite_vector_search,sqlite_vector_get,sqlite_vector_delete,sqlite_vector_count,sqlite_vector_stats,sqlite_vector_dimensions,sqlite_vector_normalize,sqlite_vector_distance: Errors like nonexistent tables, invalid identifiers, and invalid input now return{success: false, error, code, suggestion}instead of propagating as unhandled exceptions- Added
formatErrorimport fromutils/errors.jsand wrapped all 11 handlers in try/catch blocks - Security tests in
identifier-integration.test.tsupdated to assert structured error responses instead of.rejects.toThrow() - Consistent with the structured error pattern already used by all other tool groups
sqlite_vector_searchNegative Cosine Similarity Filter — Search no longer silently drops results with negative cosine similarity- Previously, the search filter
_similarity >= 0excluded rows with negative cosine similarity (dissimilar vectors) - Negative cosine similarity is valid (ranges from -1 to 1) and should be returned when within the limit
- Now filters only rows where vector parsing failed (returns
null), preserving all valid similarity scores
- Previously, the search filter
sqlite_vector_create_tableDimensions Validation — Now rejects dimensions < 1 with structured error- Previously accepted
dimensions: 0creating a table with meaninglessDEFAULT 0dimension column
- Previously accepted
sqlite_vector_distanceCosine Metric — Now returns cosine distance (1 - similarity) instead of raw cosine similarity- Previously returned cosine similarity (0 for orthogonal, 1 for identical) despite the tool being named "distance"
- Now returns cosine distance (1.0 for orthogonal, 0 for identical) consistent with euclidean distance semantics
- Does not affect
sqlite_vector_searchwhich correctly uses_similarityas a ranking score
- Window Function Structured Error Responses — All 6 window function handlers now return structured errors instead of throwing raw MCP exceptions
sqlite_window_row_number,sqlite_window_rank,sqlite_window_lag_lead,sqlite_window_running_total,sqlite_window_moving_avg,sqlite_window_ntile: Errors like nonexistent tables, invalid identifiers, and bad SQL now return{success: false, error, code, suggestion}instead of propagating as unhandled exceptions- Added
formatErrorimport fromutils/errors.jsand wrapped all 6 handlers in try/catch blocks - Window function tests updated to assert structured error responses instead of
.rejects.toThrow() - Consistent with the structured error pattern already used by all 13 stats tools
server_healthFTS5 Detection False Negative — Health check now correctly reportsfts5: truewhen FTS5 is compiled inhasFts5()previously created a_fts5_testvirtual table as a probe, which silently failed when SpatiaLite extensions were loaded- Replaced with lightweight
PRAGMA compile_optionscheck forENABLE_FTS5flag - More reliable and efficient than the virtual table creation/drop approach
- FTS5 Tool Structured Error Responses — All 4 FTS5 handlers now return structured errors instead of throwing raw MCP exceptions
sqlite_fts_create,sqlite_fts_search,sqlite_fts_rebuild,sqlite_fts_match_info: Errors like nonexistent tables, bad SQL, and invalid columns now return{success: false, error, code, suggestion}instead of propagating as unhandled exceptions- Previously, only
isFts5UnavailableError(WASM mode) was caught; all other errors were re-thrown - Consistent with the structured error pattern already used by all 13 text tools, core tools, stats tools, and JSON tools
- Security tests in
fts-injection.test.tsupdated to assert structured error responses instead of.rejects.toThrow()
sqlite_execute_codePer-Call Timeout Enforcement — Thetimeoutparameter is now respected per-call instead of being silently ignored- Previously,
timeoutwas parsed from input but never passed to the sandbox pool; all executions used the fixed 30000ms default - Added
timeoutMs?: numberparameter toISandbox.execute()andISandboxPool.execute()interfaces - All 4 implementations updated:
CodeModeSandbox,SandboxPool,WorkerSandbox,WorkerSandboxPool codemode.tsnow passes the user-specified timeout through topool.execute(code, bindings, timeoutMs)
- Previously,
sqlite_create_indexTable Existence Pre-Validation — Now returnsTABLE_NOT_FOUNDerror instead of raw SQL error for nonexistent tables- Previously returned
{success: false, message: "Write query failed: no such table: main.xyz"}(leaking implementation detail) - Now pre-validates table existence and returns
{success: false, message: "Table 'xyz' does not exist", code: "TABLE_NOT_FOUND"} - Consistent with
sqlite_describe_tableandsqlite_get_indexeswhich already pre-validate table existence
- Previously returned
sqlite_create_indexEmpty Columns Validation —CreateIndexSchema.columnsnow requires.min(1)- Previously, an empty columns array passed Zod validation and produced invalid SQL
CREATE INDEX ... ON table () - Now rejected at schema validation level with clear "Array must contain at least 1 element(s)" message
- Previously, an empty columns array passed Zod validation and produced invalid SQL
formatErrorSpecific Resource Error Codes — Native SQLite errors now return precise error codes instead of genericRESOURCE_ERRORno such tableerrors now returnTABLE_NOT_FOUNDcode (previouslyRESOURCE_ERROR)no such columnandhas no column namederrors now returnCOLUMN_NOT_FOUNDcode (previouslyRESOURCE_ERROR)- Added optional
codefield toERROR_SUGGESTIONSentries;formatErrorprefersmatch.codeover category default - Consistent across all tool groups: core
read_query/write_query, textfts_search, vectorsearch, JSONextract findSuggestionreturn type extended withcode?: stringfield- Category-level fallback codes still apply for patterns without specific
codeoverrides
ERROR_SUGGESTIONSQuery Error Pattern Coverage — 3 new patterns added for query errors that previously fell through toUNKNOWN_ERRORincomplete input→QUERY_ERRORwith suggestion to check for missing clauses or closing parenthesesmore than one statement→QUERY_ERRORwith suggestion to split into separate calls or usesqlite_execute_codetoo few parameter→QUERY_ERRORwith suggestion to match params array to placeholder count
sqlite_read_queryStatement Type Validation — Now rejects non-SELECT statements with clear error messages- Previously, INSERT/UPDATE/DELETE/DDL passed to
read_queryleaked internal better-sqlite3 message:"This statement does not return data. Use run() instead" - Now validates upfront and returns:
"Statement type not allowed: INSERT is not a SELECT query. Use sqlite_write_query for INSERT/UPDATE/DELETE, or appropriate admin tools for DDL." - Allows SELECT, PRAGMA, EXPLAIN, and WITH statements; mirrors
write_queryvalidation pattern
- Previously, INSERT/UPDATE/DELETE/DDL passed to
reset-database.ps1Verification Table List — Removed orphanedtemp_text_testentry from expected tables maptemp_text_testis not created by the seed SQL and was dead code (verification query only checkstest_%tables)
- Native Adapter Missing Codemode Tool —
sqlite_execute_codewas not registered in Native modeNativeSqliteAdapter.getToolDefinitions()was missinggetCodeModeTools()from its tool list- WASM adapter (
SqliteAdapter) already included it viagetAllToolDefinitions() - Tool filter correctly auto-injected
codemodeinto enabled groups, but the tool definition was never produced so it couldn't be registered
- Core Tool Input Validation — 5 core tool handlers now return structured errors for invalid identifiers instead of throwing raw MCP exceptions
sqlite_create_table: AddedsanitizeIdentifiervalidation for table names and empty columns array check (previously accepted empty string names and empty columns, causing orphaned tables or SQL syntax errors)sqlite_drop_table,sqlite_drop_index: Wrapped existingsanitizeIdentifiercalls in try/catch to return{success: false, message: "..."}instead of propagatingInvalidIdentifierErrorsqlite_get_indexes,sqlite_create_index: Same try/catch wrapping for identifier validation- All 5 handlers now follow the structured error response pattern:
{success: false, message: "Invalid ... name"}
sqlite_geo_nearbyreturnColumnsColumn Leakage — Lat/lon columns no longer leak into results whenreturnColumnsis specified- Previously, internally-added lat/lon columns (needed for Haversine distance calculation) were included in the response even when the user didn't request them
- Now strips lat/lon columns from results unless the user explicitly includes them in
returnColumns - Consistent with
sqlite_geo_bounding_boxwhich already respectedreturnColumnsexactly
- Geo Tool Structured Error Responses — All 3 database-accessing geo handlers now return structured errors instead of throwing raw MCP errors
sqlite_geo_nearby,sqlite_geo_bounding_box,sqlite_geo_cluster: Wrap handler logic in try-catch withformatError()for consistent{success: false, error: "..."}responses- Added
validateColumnExists()to validate lat/lon column existence before query execution; previously nonexistent columns silently returned 0 results - 6 new error path tests added for nonexistent table and column scenarios
- Admin Tool Structured Error Responses — 4 admin tool handlers now return structured errors instead of throwing raw MCP errors
sqlite_virtual_table_info: Returns{success: false, error: "Virtual table 'x' not found"}instead of throwing for nonexistent virtual tablessqlite_create_view: Catches duplicate view errors, invalid SQL, and identifier validation failures; returns{success: false, message: "..."}with contextsqlite_drop_view: Catches nonexistent view errors (whenifExists: false) and identifier validation failuressqlite_drop_virtual_table: Catches nonexistent table errors (whenifExists: false) and returns structured response- Security tests updated to assert
{success: false, message: /invalid/i}instead of.rejects.toThrow()
sqlite_verify_backupWASM False Positive — Now returns WASM limitation error upfront before attempting ATTACH- Previously, ATTACH succeeded silently in WASM (creating empty DB in virtual filesystem), causing verify to return
{success: true, valid: true}for any path including nonexistent files - Now checks
isNativeBackend()first and returns{success: false, wasmLimitation: true}immediately
- Previously, ATTACH succeeded silently in WASM (creating empty DB in virtual filesystem), causing verify to return
sqlite_restoreWASM False Positive — Now returns WASM limitation error upfront before attempting ATTACH- Previously, ATTACH succeeded silently in WASM, causing restore to "succeed" by copying empty tables from a nonexistent backup
sqlite_pragma_table_infoNonexistent Table Detection — Returns{success: false}for nonexistent tables- Previously returned
{success: true, columns: []}for tables that don't exist - Now checks if columns array is empty and returns
{success: false, error: "Table 'x' not found or has no columns"}
- Previously returned
- Admin Code Mode Positional Parameters — Added 12 missing entries in
api.tsfor admin group methodsgenerateSeries,createView,dropView,createSeriesTable,virtualTableInfo,dropVirtualTable,verifyBackup,pragmaCompileOptions,createRtreeTable,createCsvTable,analyzeCsvSchemanow support positional arg syntax- Example:
sqlite.admin.createView("my_view", "SELECT 1")now works instead of requiring object syntax
- Code Mode
normalizeParamsPrimitive Type Handling — Fixed single number/boolean args being passed raw to tool handlers- Previously,
sqlite.admin.generateSeries(1, 5, 1)passed1directly instead of{start: 1, stop: 5, step: 1} normalizeParamsnow wraps number and boolean single args using the positional parameter mapping, same as strings- Affects any method with non-string first positional params (e.g.,
generateSeries,dbstat) sqlite_stats_correlationNon-Numeric Column Validation — Now returns structured error for non-numeric columns- Previously returned
{success: true, correlation: null}when correlating text columns (e.g.,name,description) - Now validates column types via
PRAGMA table_info()and returns{success: false, code: "INVALID_INPUT"}with suggestion to use numeric columns - Correlation description says "numeric columns" — behavior now enforces this
- Previously,
- Stats Tool Zod Refinement Leak Fixes — Moved
.min()/.max()refinements from Zod schemas to handler-level validation for 3 toolssqlite_stats_histogram: Removed.min(1)frombucketsschema parameter; handler now returns{success: false, error: "'buckets' must be at least 1"}for invalid valuessqlite_stats_percentile: Removed.min(0).max(100)frompercentilesarray element schema; handler now validates each percentile value is between 0 and 100sqlite_stats_regression: Removed.min(1).max(3)fromdegreeschema parameter; handler now returns structured error for values outside 1-3 range- Previously, out-of-range values triggered raw MCP
-32602errors at the SDK boundary before the handler ran
- Stats Code Mode Positional Parameters — Fixed
statsGroupByand added 5 missing entries inapi.tsstatsGroupBy: Was mapped to["table", "column"]but actual params are["table", "valueColumn", "groupByColumn", "stat"]- Added missing positional mappings for
statsDistinct,statsSummary,statsFrequency,statsOutliers,statsHypothesis - All 13 stats methods now support positional arg syntax in
sqlite_execute_code
- Code Mode
help()Write Method Discoverability —help()now lists all methods regardless ofreadonlyflag- Previously,
readonly: truefiltered write tools before API construction, hiding them fromhelp()output - Now builds full API surface first, then wraps write methods with readonly guards returning
CODEMODE_READONLY_VIOLATIONerrors - Users can discover all available methods via
sqlite.core.help()and get clear error messages when invoking write methods in readonly mode
- Previously,
- Text Tool Code Mode Positional Parameters — Fixed 8 broken positional parameter mappings for text tools in
api.tstextSplit,textConcat,textReplacerenamed tosplit,concat,replace(matching actual method names after prefix stripping)- Added 5 missing entries:
trim,case,substring,validate,normalize - All text tools now support positional arg syntax in
sqlite_execute_code(e.g.,sqlite.text.split("table", "col", "@"))
- Text Tool Code Mode Alias — Removed broken
normalize → textNormalizealias fromMETHOD_ALIASES- The canonical method name is
normalize(nottextNormalize), so the alias was a no-op pointing to nothing
- The canonical method name is
sqlite_advanced_searchError Code — Changed fromexecuteQuerytoexecuteReadQueryfor consistent error codes- Nonexistent table errors now return
DB_QUERY_FAILEDcode instead ofUNKNOWN_ERROR
- Nonexistent table errors now return
- Security Integration Tests — Updated 4 text tool injection tests in
identifier-integration.test.ts- Tests now check for
{success: false, error: /invalid/i}pattern instead of.rejects.toThrow() - Consistent with structured error handling across all tool groups
- Fixed
text_replacetest to use correct parameter names (searchPattern/replaceWithinstead ofsearch/replace)
- Tests now check for
createIndexCode Mode Positional Parameter — Added missingindexNameto positional parameter mappingcreateIndexwas mapped as["tableName", "columns"]butindexNameis required- Code mode calls like
sqlite.core.createIndex("table", ["col"], "idx_name")now work correctly
- Text Tool
TABLE_NOT_FOUNDError Priority —validateColumnExistsnow checks table existence before column existence- Previously returned
COLUMN_NOT_FOUNDwhen table didn't exist (becausepragma_table_inforeturns empty for nonexistent tables) - Now returns
TABLE_NOT_FOUNDwith suggestion to runsqlite_list_tables - Gives users a more actionable error message for the root cause
- Previously returned
sqlite_phonetic_matchWord-Level Matching — Now splits column values into words and matches any word- Previously computed soundex/metaphone on the entire column value, missing multi-word matches (e.g., "Mouse" didn't match "Mouse Pad XL")
- Now consistent with
sqlite_advanced_searchphonetic behavior which already matched per-word - Both Soundex and Metaphone paths updated; native SQLite soundex query replaced with JS-based word splitting
- Documentation updated from "compares FIRST word only" to "matches against any word in value"
- Stats Tool Output Schema Error Responses — All 13 stats output schemas now accommodate
{success: false}error responses- 10 exported schemas in
output-schemas.tsand 3 inline schemas instats.ts(outliers, regression, hypothesis) updated - Success-specific fields made optional;
error,code,suggestionfields added - Previously,
formatError()responses failed Zod output validation because required fields likecolumn,stats,countwere missing - Mirrors the pattern already used by JSON tool schemas for structured error handling
- 10 exported schemas in
- Stats Tools Non-Numeric Column Validation —
sqlite_stats_percentile,sqlite_stats_outliers, andsqlite_stats_hypothesisnow validate column types upfrontsqlite_stats_percentile: Previously produced raw MCP output validation error (string values in numeric schema); now returns{success: false, code: "INVALID_INPUT"}sqlite_stats_outliers: Previously generated SQL withNaNvalues causingDB_QUERY_FAILED; now returns structured error before query executionsqlite_stats_hypothesis: Previously returnedUNKNOWN_ERRORwith vague message; now returnsINVALID_INPUTwith clear suggestion- Shared
validateNumericColumn()helper extracted fromcreateCorrelationToolfor reuse across all three handlers
- Stats Code Mode Positional Parameters (Round 2) — Fixed 2 remaining positional parameter mappings in
api.tsstatsTopN: Was["table", "column"], missingnandorderDirection— fixed to["table", "column", "n", "orderDirection"]statsHypothesis: HadcolumnandtestTypeswapped — fixed to["table", "column", "testType"]statsHypothesis: Added missingexpectedMeanas 4th positional param — enablessqlite.stats.statsHypothesis("table", "col", "ttest_one", 25)without object syntax
- Stats Code Mode Positional Parameters (Round 3) — Added
whereClauseandselectColumnsto positional parameter mappings inapi.ts- 12 stats methods (
statsBasic,statsCount,statsGroupBy,statsHistogram,statsPercentile,statsCorrelation,statsRegression,statsDistinct,statsSummary,statsFrequency,statsOutliers,statsHypothesis) now accept trailingwhereClausepositional arg statsTopN: AddedselectColumnsas 5th positional param — enablessqlite.stats.statsTopN("table", "col", 3, "desc", ["id", "name"])without object syntax- Previously, trailing positional args for
whereClauseandselectColumnswere silently dropped
- 12 stats methods (
- Stats Code Mode Help Examples — Fixed incorrect method names in
GROUP_EXAMPLESfor stats groupsqlite.stats.basic()→sqlite.stats.statsBasic(),.histogram()→.statsHistogram(),.percentile()→.statsPercentile()- Stats group uses
KEEP_PREFIX_GROUPSso methods retain thestatsprefix; examples now match actual API
- Stats Tools Numeric Column Validation (Round 2) — Added
validateNumericColumnto 4 additional stats toolssqlite_stats_basic: Previously returned meaningless results (sum: 0, avg: 0, min/max: null) for text columns; now returns structuredINVALID_INPUTerrorsqlite_stats_histogram: Previously generated corrupt SQL with NaN bucket boundaries for text columns; now returns structured error before query executionsqlite_stats_regression: Previously returned raw MCP output validation error (NaN coefficients) for text columns; now validates both xColumn and yColumn upfrontsqlite_stats_group_by: Previously returnedstat_value: 0for AVG/SUM/MIN/MAX on text columns; now validates valueColumn is numeric for non-count aggregations (count stat remains unrestricted)
- Stats Code Mode Positional Parameters (Round 4) — Fixed
statsCountmissingdistinctin positional parameter mapping- Was
["table", "column", "whereClause"]—distinctboolean passed as 3rd arg was mapped towhereClause, causing Zod validation error - Fixed to
["table", "column", "distinct", "whereClause"]— enablessqlite.stats.statsCount("table", "col", true)syntax
- Was
- Codemode Positional Parameter Mapping — Fixed incorrect parameter name mappings in
api.tsreadQueryandwriteQuerymapped to"sql"but actual schema uses"query"— correcteddescribeTable,dropTable,getIndexesmapped to"table"but actual schema uses"tableName"— correctedcreateTable,createIndexfirst positional param mapped to"table"instead of"tableName"— correctedServerInstructions.tsexamples updated to match corrected mappings
- Codemode JSON Positional Parameter Mapping — Fixed 16 incorrect parameter mappings for JSON code mode methods
validatePath,pretty,validwere mismapped to["table", "column", ...]instead of"path","json","json"respectivelyextract,set,remove,type,arrayLength,arrayAppend,keys,each,update,mergewere missingwhereClausepositional paraminsertmissingdata,selectmissingpaths,querymissingfilterPathsparams- Calling
sqlite.json.extract("table", "col", "$.path", "id = 1")now correctly maps the 4th arg towhereClause
sqlite_create_indexMisleading Message for Duplicate Index Name — Fixed IF NOT EXISTS returning false "created" message- When an index name already exists,
CREATE INDEX IF NOT EXISTSsilently does nothing but the handler always reported "created on table(column)" - Now checks index existence before executing and returns
"already exists (no changes made)"when the index is pre-existing - Mirrors the pattern already used by
sqlite_create_tablefor duplicate table names
- When an index name already exists,
sqlite_execute_codeNegativememoryUsedMbValues — Clamped memory metric toMath.max(0, ...)- Both
worker-sandbox.tsandsandbox.tsmeasured heap delta on the main thread, which could go negative due to GC during worker execution - Values like
-4.76 MBare now reported as0 MBinstead
- Both
sqlite_write_queryStatement Type Validation — Now rejects non-DML statements with structured errors- Only allows INSERT, UPDATE, DELETE, and REPLACE statements
- SELECT, PRAGMA, EXPLAIN, and DDL (CREATE, ALTER, DROP, TRUNCATE) are rejected with clear error messages
- Prevents accidental data loss from DDL via write_query (previously accepted and executed
DROP TABLE)
- WASM FTS5 Tool Exclusion — FTS5 tools no longer registered in WASM mode
- Removed
getFtsTools()from shared WASM tool index (tools/index.ts) - FTS5 tools (
sqlite_fts_create,sqlite_fts_search,sqlite_fts_rebuild,sqlite_fts_match_info) remain available in native mode only - Previously, 4 FTS5 tools were registered in WASM but always returned
{success: false, error: "FTS5 module unavailable"} - WASM tool counts corrected:
starter48→44,search36→32,full102→98,textgroup 17→13 - Updated README.md, DOCKER_README.md, ToolConstants.ts, ServerInstructions.ts
- Updated fts.test.ts and index.test.ts to verify exclusion
- Removed
sqlite_create_json_collectionNon-Atomic Table Creation — Index path validation now runs before table creation- Previously, the table was created first, then index paths were validated one-by-one
- An invalid index path returned
{success: false}but left the table behind (partial creation) - Now validates all index paths upfront before executing
CREATE TABLE - DOCKER_README Documentation Sync — Synchronized Docker Hub README with main README content
- Added Resources (8) table with efficiency tip and Prompts (10) table
- Added SQLite Extensions section with Docker-specific SpatiaLite/CSV instructions
- Added OAuth 2.1 supported scopes table and Docker quick start example
- Added stateless mode section for serverless Docker deployments
- Added performance tuning tip for schema cache TTL configuration
- Expanded HTTP endpoints from bullet list to table format with session management details
- Fixed formatting bug: unclosed 4-backtick code block in legacy syntax section
- README Streamlining — Removed redundant sections to reduce README from 712 to ~590 lines
- Removed Table of Contents (GitHub renders one natively)
- Merged Quick Test into Quick Start as a "Verify It Works" substep
- Removed Security Features checklist (duplicated by "What Sets Us Apart" table)
- Removed Tool Categories table (redundant with Tool Groups table in Tool Filtering)
- Removed Backend Options table and Transaction/Window tool listings (reference-level detail for Wiki)
- Merged standalone Configuration section into OAuth section as a one-liner
- Promoted Extensions, Resources, and Prompts to top-level sections
- ESLint v10 Compatibility — Fixed 11 new lint errors introduced by the ESLint v10 major upgrade
- Added
{ cause }to re-thrown errors inNativeSqliteAdapter.ts,spatialite.ts,SqliteAdapter.ts(preserve-caught-error) - Removed useless initial assignments in
SchemaManager.ts,SqliteAdapter.ts,admin.ts,stats.ts(no-useless-assignment) - Fixed unsafe
express.json()call inhttp.ts(no-unsafe-call)
- Added
- Added
lint:jsonnpm script for agent-readable ESLint output (eslint-results.json) - Added
.gitattributesto normalize line endings to LF on all platforms - Added test suite badges (941 tests, 80% coverage) to both READMEs
- Query Normalization: Strip trailing whitespace and semicolons before injecting safety
LIMIT, preventing invalid SQL likeSELECT ...; LIMIT 1000 - CTE Write Support:
sqlite_write_querynow correctly accepts CTE-prefixed DML (WITH ... INSERT/UPDATE/DELETE/REPLACE) by parsing past parenthesized CTE bodies to find the main DML keyword - Statement Validation: Removed
UPSERTfrom allowed write prefixes — it is not a valid SQLite leading keyword - SQL Injection Hardening: Replaced string interpolation with parameterized queries for table name filters in
sqlite_get_indexesandsqlite_index_stats - Column Validation: Optimized
validateColumnsExistto fetch all columns in a singlepragma_table_infoquery and check membership in-memory, eliminating N+1 query roundtrips - Structured Errors: All 3 native transaction savepoint handlers (
savepoint,release,rollback_to) now returnformatHandlerError(ValidationError)for invalid names instead of bare{success: false}objects - WASM Capability: Corrected
fullTextSearchcapability flag tofalsefor WASM/sql.js builds (FTS5 is not available) - Constraint Analysis: Removed redundant no-op
.replace(/_/g, "_")in foreign key column inference - Encoding: Fixed mojibake em dash (
â€"→—) in admin barrel index JSDoc - CodeQL: Fixed missing regex anchor in icon URL test assertion
- CodeQL: Removed 10 unused imports across 8 test files
- SQL Injection: Replaced string interpolation with parameter binding in column validation queries (
validateTableExists,validateColumnExists,validateColumnsExist) - SQL Injection: Replaced string interpolation with parameter binding in schema fallback
fallBackGetIndexestable filter - Read Query: Deny-by-default for
sqlite_read_query— unrecognized statement types are now blocked instead of falling through to the adapter - Verify Backup: Use structured
formatHandlerErrorinsqlite_verify_backupearly-return error paths (empty path, file not found, ATTACH failure) - Transaction Methods: Throw
ValidationErrorinstead of genericErrorfor invalid savepoint names in native transaction methods - Index Detection: Case-insensitive
UNIQUEdetection insqlite_get_indexes(normalize DDL to uppercase before matching) - Metadata: Updated
server.jsontool count from 122 to 139 - CodeQL: Removed unused
calledPragmavariable in vtable test - SQL Injection: Narrowed
UNION SELECT/UNION ALL SELECTdangerous-pattern regexes to require semicolon-delimited context (;\\s*UNION), allowing legitimate UNION queries - PRAGMA Safety: Block mutating PRAGMAs (assignment form with
=) insqlite_read_queryto prevent privilege escalation viawritable_schema,journal_mode, etc. - Verify Backup: Wrapped
DETACH DATABASEinfinallyblock with try/catch to prevent detach failures from overriding successful verification results - Optimize Tool: Added try/catch +
formatHandlerErrortosqlite_optimizehandler for consistent structured error responses on parse or runtime failures - Structured Errors: Added
structuredContentto error responses in the tool registration wrapper when tools haveoutputSchema, ensuring clients receive machine-readable error payloads - PRAGMA Safety: Block mutating PRAGMAs in
sqlite_read_query— assignment form (=) always blocked; function-call form (PRAGMA name(...)) checked against read-only allowlist (table_info, index_list, foreign_key_list, etc.) - Optimize Progress: Fixed off-by-one progress tracking in analyze branch (
step + 1→++step) - Adapter Version: Updated
SqliteAdapter.versionfrom1.0.0to1.1.0to matchpackage.json - Error Codes: Aligned schema-manager error codes with canonical tool-level codes (
SQLITE_INVALID_TABLE→INVALID_TABLE,SQLITE_TABLE_NOT_FOUND→TABLE_NOT_FOUND) - Transaction Methods: Removed local
ValidationErrorclass in favor of plainError— callers already wrap withformatHandlerError - Transaction Rollback: Preserved
formatted.errorin rollback catch block instead of overwriting with generic rollback message - SpatiaLite Loader: Windows PATH resolution now derives directory from
customPath(when provided) instead of onlySPATIALITE_PATHenv var; renamed shadowpathvariable - CI E2E: Added database seeding step (
sqlite3 test.db < test-database.sql) toe2e.yml—test.dbis gitignored and absent on fresh CI checkout, causing WASM E2E tests to fail with empty database - Transaction Mode: Normalized transaction mode input to lowercase —
IMMEDIATEandImmediatenow correctly resolve toimmediateinstead of silently defaulting todeferred - Transaction Rollback: Wrapped
rollbackTransaction()in try/catch to preserve original error context if rollback itself fails - Verify Backup Errors: Error codes (
FILE_NOT_FOUND,ATTACH_FAILED) now passed throughValidationErrorconstructor instead of overriding afterformatHandlerErrorspread - Dockerfile Healthcheck: Transport-aware healthcheck — only runs
curl /healthin HTTP mode; falls back to lightweight Node.js check for stdio to prevent false-healthy status - E2E: CSV payload test now reads
payload.error(notpayload.message) for extension-unavailable skip detection, fixing CI failures on Linux where the Windows-only CSV extension is absent
- CTE Write-Bypass:
sqlite_read_querynow blocksWITH ... INSERT/UPDATE/DELETE— parses past CTE preamble to verify main statement isSELECTorEXPLAIN - PRAGMA Hardening: Assignment detection uses anchored regex (
^PRAGMA\s+name\s*=) instead ofincludes("=")to avoid false positives in string literals; function-call regex handles schema-qualified names (PRAGMA main.table_info(...)) - SQL Comment Injection: Comment-style patterns (
--,/* */) now tested against string-literal-stripped SQL to prevent false positives on quoted values likeSELECT 'a--b' - Log Injection (CodeQL): Logger taint-break uses char-code round-trip (
String.fromCharCode) to sever CodeQL data-flow tracking chain for sanitized output - Strict Validation: Removed
.strict()from all Zod tool input schemas across all tool groups..strict()maps toadditionalProperties: falsein JSON Schema, which causes the MCP SDK to reject unrecognized keys at the framework boundary before handlers can catch, producing raw-32602errors instead of structured responses. Handler-level validation (regex, enum checks) already guards against malformed input. - SQL Injection: Added strong regex validation to
savepointnames in the Native SQLite transaction methods to prevent potential arbitrary SQL injection. - CORS Advisory: Updated
README.mdandDOCKER_README.mdto explicitly warn about the permissive["*"]default CORS property in production HTTP deployments. - Unified Audit: SHA-pinned all GitHub Actions in
lint-and-test.ymlande2e.ymlfor supply chain safety. Updated stale v4 SHAs to current v6 ine2e.yml. Removed manually-maintainedLABEL versionfromDockerfileto prevent version drift. Fixedflatteddependency vulnerability (GHSA-25h7-pfq9-p65f). - DNS Rebinding: Added
localhostHostValidation()middleware from MCP SDK to the HTTP transport to prevent DNS rebinding attacks. - Supply Chain: SHA-pinned remaining 2 un-pinned CI actions (
actions/checkout,actions/setup-node) in the benchmarks job oflint-and-test.yml. - Supply Chain: Bumped GitHub Actions to latest major versions (Node 24 runtime):
docker/login-actionv3 → v4docker/build-push-actionv6 → v7docker/metadata-actionv5 → v6docker/setup-buildx-actionv3 → v4actions/upload-artifactv6 → v7actions/download-artifactv7 → v8
- Transitive Updates: Fixed multiple vulnerabilities in transitive dependencies by updating
package-lock.jsonvianpm update:minimatch: ReDoS inmatchOne()combinatorial backtracking via multiple non-adjacent GLOBSTAR segments.honoand@hono/node-server: Arbitrary file access viaserveStatic, authorization bypass for protected static paths, SSE Control Field Injection, Cookie Attribute Injection, and Prototype Pollution inparseBody.express-rate-limit: IPv4-mapped IPv6 addresses bypassing per-client rate limiting on dual-stack networks.
- Code Quality Audit — Table Name Validation — Added regex guard (
/^[a-zA-Z_][a-zA-Z0-9_]*$/) to native adapter'sdescribeTablefallback- WASM adapter already had this guard; native adapter's fallback path was missing it
- Code Quality Audit — Missing WHERE Clause Validation — Added
validateWhereClause()to 15 SQL interpolation points across 5 JSON tool filesjson-operations/crud.ts(7 handlers),json-operations/query.ts(5 handlers),json-operations/transform.ts(2 handlers)json-helpers/read.ts(1 handler),json-helpers/write.ts(2 handlers)- These tools interpolated
input.whereClausedirectly into SQL without validation, unlike text/stats/vector/window tools which all calledvalidateWhereClause()
- Security Audit Remediation — Addressed 4 findings from comprehensive security audit
- Fixed transitive
honovulnerability (GHSA-v8w9-8mx6-g223) vianpm audit fix - Added HTTP server timeouts:
setTimeout(120s),keepAliveTimeout(65s),headersTimeout(66s)to prevent slowloris-style DoS attacks - SHA-pinned all GitHub Actions across 4 CI workflows (
lint-and-test.yml,codeql.yml,publish-npm.yml,docker-publish.yml) to prevent supply chain attacks via tag hijacking - Hardened Docker Scout security gate to fail-fast on non-timeout scan errors instead of silently continuing
- Fixed transitive
- NPM Audit Remediation — Patched high severity vulnerabilities in transitive dependencies
@hono/node-server: updated to 1.19.11hono: updated to 4.12.5
- Docker CVE Remediation — Patched npm-bundled transitive dependencies in Dockerfile (both stages)
tar: 7.5.7 → 7.5.8 (CVE-2026-26960: path traversal, HIGH 7.1)minimatch: 10.1.2 → 10.2.4 (CVE-2026-26996: ReDoS, HIGH 8.7)
- Security Audit Remediation — Addressed findings from exhaustive codebase security audit
- CI
npm auditgate now hard-fails on moderate+ vulnerabilities (removedcontinue-on-error) - Added
Referrer-PolicyandStrict-Transport-SecurityHTTP security headers (5 → 7 total) - WHERE clause validation now blocks
; SELECTstacked query injection - Removed dead
new InvalidTokenError()construction in auth middleware - Updated
SECURITY.mdsupported versions to1.x.x - Fixed Dockerfile labels (version
1.0.2, tool count124)
- CI
- GitHub Release badge to READMEs (dynamic version display)
- npm Publishing — Automated npm publishing workflow on GitHub releases
publish-npm.yml: NPM publish workflow triggered on release events.npmignore: Reduces npm package size from 2.5MB to ~200KB
- README Badges — npm version, Docker pulls, MCP Registry badges
- MCP Registry Integration —
server.jsonwith npm + Docker packages
- MIT license badge color (yellow → blue) for consistency
-
Docker Release Infrastructure — Complete CI/CD pipeline for Docker Hub publishing
lint-and-test.yml: CI workflow with Node.js 22/24/25 matrix testing, ESLint, TypeScript checksdocker-publish.yml: Docker deploy workflow with security scanning, multi-platform builds (amd64/arm64), manifest mergeDockerfile: Multi-stage build with better-sqlite3 native compilation, non-root user, security patches.dockerignore: Excludes dev files, tests, and databases from imageDOCKER_README.md: Docker Hub README with quick start, tool filtering, security documentationDOCKER_DEPLOYMENT_SETUP.md: Setup guide for GitHub secrets and deployment workflow
-
Security Test Coverage Expansion — 12 new/enhanced test files improving coverage for security-critical utilities
tests/utils/quoteIdentifier.test.ts: 32 tests for identifier sanitization edge cases (empty, whitespace, control chars, quotes)tests/security/validateQuery.test.ts: 23 tests forDatabaseAdapter.validateQuerysecurity patternstests/adapters/sqlite/resources.test.ts: 10 tests for all 8 MCP resource handlerstests/adapters/sqlite/prompts.test.ts: 16 tests for all 10 MCP prompt handlerstests/utils/insightsManager.test.ts: 16 tests for the insights memo singletontests/utils/progress-utils.test.ts: 17 tests for MCP progress notification utilitiestests/utils/annotations.test.ts: 21 tests for tool and resource annotation presetstests/adapters/sqlite/json-utils.test.ts: 67 tests for JSON normalization, JSONB support, SQL generation, validationtests/adapters/sqlite-native/NativeSqliteAdapter.test.ts: 39 tests for native adapter (connection, queries, schema, capabilities)- Enhanced
logger.test.tswith 7 additional ModuleLogger convenience method tests (notice, warn, warning, critical, alert, emergency) - Enhanced
security-injection.test.tswithsanitizeWhereClausetests - Enhanced
ToolFilter.test.tswith edge case tests (comma-only strings, meta-group exclusion, summary generation) - Coverage improvements:
identifiers.ts65→97%,where-clause.ts80→100%,ToolFilter.ts91→96%,resources.ts22→97%,prompts.ts23→87%,insightsManager.ts22→100%,progress-utils.ts0→100%,annotations.ts90→100%,resourceAnnotations.ts66→100%,json-utils.ts43→97%,logger.ts85→97%,NativeSqliteAdapter.ts49→65%+
-
sqlite_spatialite_analyzeGeometry Output Control — NewincludeGeometryparameter to reduce payload size- When
false(default), omits full WKT geometry fromnearest_neighborandpoint_in_polygonresults - When
true, includessource_geomandtarget_geomWKT fields as before - Significantly reduces payload size for proximity analysis (geometry can be 100+ characters per row)
- When
-
sqlite_dbstatSystem Table Filter — NewexcludeSystemTablesparameter to hide SpatiaLite metadata- When
true, filters out SpatiaLite system tables from storage statistics (57 tables → ~12 user tables) - Applies to both summarize mode and default raw page-level mode
- Provides parity with
sqlite_list_tablesandsqlite_get_indexessystem table filtering - Default is
falseto preserve backward compatibility
- When
-
sqlite_list_tablesTool Description — Fixed misleading "row counts" description- Changed tool description in
core.tsfrom "row counts" to "column counts" to match actual output - Tool returns
columnCountper table, not row counts
- Changed tool description in
-
sqlite_json_normalize_columnOutput Format Control — NewoutputFormatparameter for normalization outputpreserve(default): Keeps original format (text→text, JSONB→JSONB)text: Always outputs normalized JSON as textjsonb: Outputs normalized JSON in JSONB binary format- Enables normalizing JSONB columns without losing binary format efficiency
- Response includes
outputFormatfield indicating which format was applied
-
sqlite_list_viewsSystem View Filter — NewexcludeSystemViewsparameter to hide SpatiaLite views- When
true(default), filters out SpatiaLite system views (geom_cols_ref_sys,spatial_ref_sys_all,vector_layers, etc.) - Reduces noise in view listings for spatial databases (7 views → 1 user view)
- Set to
falseto include all views
- When
-
sqlite_get_indexesSystem Index Filter — NewexcludeSystemIndexesparameter to hide SpatiaLite indexes- When
true, filters out SpatiaLite system indexes (idx_spatial_ref_sys,idx_srid_geocols,idx_viewsjoin,idx_virtssrid, etc.) - Provides parity with
sqlite_list_tablesparameterexcludeSystemTables
- When
-
sqlite_list_tablesSystem Table Filter — NewexcludeSystemTablesparameter to hide SpatiaLite metadata- When
true, filters out SpatiaLite system tables (geometry_columns,spatial_ref_sys,spatialite_history,vector_layers, etc.) - Reduces noise in table listings for spatial databases (38 tables → 12 user tables)
- When
-
WASM vs Native Documentation — Added feature comparison table to
ServerInstructions.ts- Lists FTS5, transactions, window functions, SpatiaLite, and soundex availability
- Token-efficient format optimized for AI agent consumption
-
Polynomial Regression Support —
sqlite_stats_regressionnow supports degree 1-3 polynomial fits- Linear (degree=1), quadratic (degree=2), and cubic (degree=3) regression via OLS normal equation
- Matrix operations (transpose, multiply, Gauss-Jordan inverse) implemented in pure TypeScript
- Output includes named coefficients (
intercept,linear,quadratic,cubic) instead of genericslope - R² calculation uses sum of squared residuals for accurate goodness-of-fit measurement
- Equation string displays polynomial terms (e.g.,
y = 2.0000x² + 3.0000x + 5.0000)
-
WASM Mode Core Tool Compatibility — Fixed issues discovered during WASM mode testing
server_healthnow correctly reportsfilePathfromconnectionStringwhenfilePathis not setsqlite_list_tablesnow gracefully handles FTS5 virtual tables in WASM mode (sql.js lacks FTS5 module)- FTS5 shadow tables (
_fts_*) are automatically skipped in table listings - Tables that fail
PRAGMA table_info()are skipped rather than failing the entire operation COUNT(*)errors on virtual tables returnrowCount: 0instead of throwing
-
MCP Resource Template Registration — Fixed
sqlite_table_schematemplated resource not matching client requests- Updated
registerResource()inNativeSqliteAdapterto detect URI templates (containing{param}placeholders) - Template resources now use MCP SDK's
ResourceTemplateclass for proper URI matching - Static resources continue using simple string URI registration
- Allows clients to request resources like
sqlite://table/test_products/schemaand have them matched correctly
- Updated
-
Missing
getAllIndexes()Method — AddedgetAllIndexes()toNativeSqliteAdapter- Required by
sqlite_indexesresource but was missing in native adapter - Returns all user-created indexes with table name, column list, and uniqueness info
- Queries
sqlite_masterandPRAGMA index_info()for complete index metadata
- Required by
-
PRAGMA Compile Options Filter —
sqlite_pragma_compile_optionsnow supportsfilterparameter- Case-insensitive substring match to limit returned options (e.g.,
filter: "FTS"returns only FTS-related options) - Reduces payload size for targeted queries (58 options → filtered subset)
- Case-insensitive substring match to limit returned options (e.g.,
-
Database Stats Summarize Mode —
sqlite_dbstatnow supportssummarizeparameter- When
summarize: true, returns aggregated per-table stats instead of raw page-level data - Summary includes:
pageCount,totalPayload,totalUnused,totalCells,maxPayloadper table - Reduces response size (27 rows → 1 row per table) while providing actionable storage metrics
- When
-
Stats Tool Column Selection —
sqlite_stats_top_nnow supportsselectColumnsparameter- Limits returned columns to only those specified (reduces payload size for large tables)
- Default behavior unchanged: returns all columns when
selectColumnsis not provided - Columns are validated and sanitized for SQL injection protection
-
FTS5 Auto-Sync Triggers —
sqlite_fts_createnow automatically creates sync triggers- INSERT/UPDATE/DELETE triggers keep FTS5 index synchronized with source table in real-time
- New
createTriggersoption (default:true) to control trigger creation - FTS tables are automatically populated with existing data on creation via
rebuild - Trigger naming convention:
{ftsTable}_ai(insert),{ftsTable}_ad(delete),{ftsTable}_au(update) - Response includes
triggersCreatedarray listing created trigger names
-
FTS5 Wildcard Query Support —
sqlite_fts_searchnow supports list-all queries- Query
*or empty string returns all FTS table contents without MATCH filtering - Useful for browsing FTS index contents or debugging FTS configuration
- Returns rows ordered by rowid with
rank: null
- Query
-
Phonetic Match Verbosity Control —
sqlite_phonetic_matchnow supportsincludeRowDataoption- New
includeRowDataparameter (default:true) to control full row data inclusion - Set to
falsefor compact responses with onlyvalueandphoneticCodeper match - Backward compatible: existing calls behave identically
- New
-
SQLite Extension Support — Added CLI flags and configuration for loadable SQLite extensions
--csvflag to load CSV extension for CSV virtual tables--spatialiteflag to load SpatiaLite extension for GIS capabilitiesCSV_EXTENSION_PATHandSPATIALITE_PATHenvironment variables for custom extension paths- Platform-aware extension binary detection (Windows/Linux/macOS)
- README documentation for built-in vs loadable extensions with installation instructions
-
Test Infrastructure — Migrated tests to native SQLite adapter for full feature coverage
- Added
tests/utils/test-adapter.tsfactory for centralized adapter instantiation - All 9 SQLite test files now use
NativeSqliteAdapter(better-sqlite3) instead of sql.js WASM - FTS5 tests now execute properly (previously skipped due to WASM limitations)
- Added
-
Comprehensive Test Infrastructure — Test database setup for systematic tool group testing
test-server/test-database.sql: Seed data with 10 tables and 409 rows covering all 7 tool groupstest-server/reset-database.ps1: PowerShell script to reset database to clean state with verificationtest-server/test-groups/: Individual test guides for each tool group (core, json, text, stats, vector, admin, geo)- Uses ESM-compatible Node.js scripts with better-sqlite3 for cross-platform reset
- Test tables: products, orders, json_docs, articles, users, measurements, embeddings, locations, categories, events
-
HTTP/SSE Streaming Transport — Enhanced HTTP transport with session management and SSE
- Stateful mode (default): Multi-session management with SSE streaming for notifications
- Stateless mode (
--stateless): Lightweight serverless-compatible mode for Lambda/Workers POST /mcp: JSON-RPC requests with session managementGET /mcp: SSE stream for server-to-client notificationsDELETE /mcp: Session termination endpoint- Enhanced CORS headers for
mcp-session-idandLast-Event-ID - Health endpoint reports active session count and transport mode
-
Business Insights Memo — New tool and resource for capturing analysis insights
sqlite_append_insighttool: Add business insights discovered during data analysismemo://insightsresource: Synthesized memo of all captured insights- Insights manager singleton for in-memory insight storage
-
Summarize Table Prompt — Intelligent table analysis workflow
sqlite_summarize_tableprompt with configurable analysis depth- Supports basic, detailed, and comprehensive analysis modes
-
Advanced Search Tool — Multi-mode text search
sqlite_advanced_searchtool combining exact, fuzzy (Levenshtein), and phonetic (Soundex) matching- Configurable threshold and technique selection
-
Hybrid Search Workflow Prompt — Combined FTS5 + vector search
sqlite_hybrid_search_workflowprompt for hybrid search implementation- Guides through schema setup, query structure, and weight tuning
-
Interactive Demo Prompt — Flagship MCP demonstration
sqlite_demoprompt for interactive capability walkthrough- Guides through data creation, querying, and insight capture
-
MCP Progress Notifications (2025-11-25) — Real-time progress updates for long-running operations
- New
src/utils/progress-utils.tsmodule withsendProgress()andbuildProgressContext()utilities - Extended
RequestContextinterface with optionalserverandprogressTokenfields sqlite_restore: 3-phase progress (prepare → restore → verify)sqlite_optimize: Dynamic multi-phase progress (start → reindex → analyze → complete)sqlite_vacuum: 2-phase progress (start → complete)- Notifications are best-effort and require client support for
progressTokenin_meta
- New
-
Modern Tool Registration — Migrated from deprecated
server.tool()toserver.registerTool()API- Both
SqliteAdapterandNativeSqliteAdapternow use modern pattern - Full
inputSchema/outputSchemapassed (not just.shape) - MCP 2025-11-25
structuredContentreturned whenoutputSchemais present - Progress token extraction from
extra._metaenables progress notifications - Removed all eslint-disable comments for deprecated API usage
- Both
-
Metadata Caching Pattern — TTL-based schema caching ported from mysql-mcp
- New
SchemaManager.tsmodule with configurable cache TTL (default: 5s) - Schema, tables, and indexes cached to reduce repeated introspection queries
- Auto-invalidation on DDL operations (CREATE/ALTER/DROP) in all query methods
- Fixed N+1 query pattern in
sqlite://indexesresource - ToolFilter caching for O(1) tool group lookups
METADATA_CACHE_TTL_MSenvironment variable for tuning (documented in README)
- New
-
SpatiaLite Geospatial Tools (Native-only) — 7 new tools for GIS capabilities
sqlite_spatialite_load— Load SpatiaLite extensionsqlite_spatialite_create_table— Create tables with geometry columnssqlite_spatialite_query— Execute spatial SQL (ST_Distance, ST_Within, etc.)sqlite_spatialite_analyze— Spatial analysis (nearest neighbor, point-in-polygon)sqlite_spatialite_index— Create/manage spatial R-Tree indexessqlite_spatialite_transform— Geometry operations (buffer, union, intersection)sqlite_spatialite_import— Import WKT/GeoJSON data- Tools gracefully fail with helpful error if SpatiaLite extension not installed
-
Geo Tool Group — New dedicated group for geospatial tools
- Moved 4 Haversine-based geo tools from
admintogeogroup - SpatiaLite tools also in
geogroup (7 Native-only tools) - New
spatialshortcut: Core + Geo + Vector (23 WASM / 30 Native tools) - 7 tool groups now available (was 6)
- Moved 4 Haversine-based geo tools from
-
Admin/PRAGMA Tools — Added 8 new database administration tools (100 total)
sqlite_restore: Restore database from backup filesqlite_verify_backup: Verify backup file integrity without restoringsqlite_index_stats: Get detailed index statistics with column infosqlite_pragma_compile_options: List SQLite compile-time optionssqlite_pragma_database_list: List all attached databasessqlite_pragma_optimize: Run PRAGMA optimize for performance tuningsqlite_pragma_settings: Get or set PRAGMA valuessqlite_pragma_table_info: Get detailed table column metadata
-
MCP Tool Annotations (2025-11-25 spec) — Added behavioral hints to all 73 tools
readOnlyHint: Indicates read-only tools (SELECT queries, schema inspection)destructiveHint: Warns about irreversible operations (DROP, DELETE, TRUNCATE)idempotentHint: Marks safe-to-retry operations (CREATE IF NOT EXISTS)- Annotation presets in
src/utils/annotations.ts: READ_ONLY, WRITE, DESTRUCTIVE, IDEMPOTENT, ADMIN - Helper functions:
readOnly(),write(),destructive(),idempotent(),admin()
-
MCP Resource Annotations (2025-11-25 spec) — Added metadata hints to all 7 resources
audience: Intended consumer (user,assistant, or both)priority: Display ordering hint (0-1 range)lastModified: ISO 8601 timestamp for cache invalidation- Annotation presets in
src/utils/resourceAnnotations.ts: HIGH_PRIORITY, MEDIUM_PRIORITY, LOW_PRIORITY
-
Whitelist-Style Tool Filtering — Enhanced tool filtering to match postgres-mcp syntax
- Whitelist mode: Specify only the groups you want (e.g.,
core,json,text) - Shortcuts: Predefined bundles (
starter,analytics,search,spatial,minimal,full) - Mixed mode: Combine whitelist with exclusions (e.g.,
starter,-fts5) - Backward compatible: Legacy exclusion syntax (
-vector,-geo) still works - See README "Tool Filtering" section for documentation
- Whitelist mode: Specify only the groups you want (e.g.,
-
ServerInstructions for AI Agents — Added automated instruction delivery to MCP clients
- New
src/constants/ServerInstructions.tswith tiered instruction levels (essential/standard/full) - Instructions automatically passed to MCP server during initialization
- Includes usage examples for JSON, Vector, FTS5, Stats, Geo, Window Functions, and Transactions
- Following patterns from memory-journal-mcp and postgres-mcp
- New
-
MCP Enhanced Logging — Full MCP protocol-compliant structured logging
- RFC 5424 severity levels: debug, info, notice, warning, error, critical, alert, emergency
- Module-prefixed error codes (e.g.,
DB_CONNECT_FAILED,AUTH_TOKEN_INVALID) - Structured log format:
[timestamp] [LEVEL] [MODULE] [CODE] message {context} - Module-scoped loggers via
logger.forModule()andlogger.child() - Sensitive data redaction for OAuth 2.1 configuration fields
- Stack trace inclusion for error-level logs with sanitization
- Log injection prevention via control character sanitization
-
Initial repository setup
-
Project documentation (README, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY)
-
GitHub workflows (CodeQL, Dependabot)
-
Issue and PR templates
-
ServerInstructions.ts Admin Tool Documentation — Improved admin tool documentation clarity
sqlite_dbstat: Clarified JS fallback provides counts only (not per-table stats); updated WASM vs Native tablesqlite_pragma_compile_options: Added note that WASM may show FTS3, not FTS5- R-Tree and CSV tools: Clarified these return graceful errors with
wasmLimitation: truein WASM mode
-
ServerInstructions.ts Text Tool Documentation — Improved fuzzy_match and phonetic_match examples
- Clarified tokenize behavior:
tokenize:falsefor full-string matching vs default token mode - Added
includeRowData:falsetip for phonetic matching to reduce payload size - Fixed example search term ("laptop" instead of "laptp" for clearer demonstration)
- Clarified tokenize behavior:
-
sqlite_dbstatResponse Field Naming — Renamed response fields for clarity when usingsummarize: true- Changed
tableCounttoobjectCountandtablestoobjects - dbstat returns storage stats for all database objects (tables and indexes), not just tables
- More accurately reflects the actual content of the response
- Changed
-
sqlite_spatialite_transformAdaptive Buffer Simplification — Buffer tolerance now scales with buffer distance- Default tolerance changed from fixed 0.0001 to adaptive
max(0.0001, distance * 0.01) - Larger buffers (e.g., 0.1 degrees) now produce ~50 vertices instead of 96+ for more compact WKT
- Smaller buffers retain precision with the 0.0001 floor
- Default tolerance changed from fixed 0.0001 to adaptive
-
sqlite_index_statsSystem Index Filter — NewexcludeSystemIndexesparameter to hide SpatiaLite system indexes- When
true(default), filters out SpatiaLite system indexes (idx_spatial_ref_sys,idx_srid_geocols,idx_viewsjoin,idx_virtssrid) - Provides parity with
sqlite_dbstatandsqlite_list_tablessystem table filtering - Set to
falseto include all indexes
- When
-
sqlite_pragma_compile_optionsDescription — Enhanced tool description to mention filter parameter- Description now notes "Use the filter parameter to reduce output (~50+ options by default)"
- Helps agents know upfront how to avoid large payloads
-
sqlite_dbstatParameter Clarification — UpdatedexcludeSystemTablesdescription for accuracy- Description now clarifies it filters "SpatiaLite system tables and indexes" (not just tables)
- Reflects actual filtering behavior which includes SpatiaLite indexes in dbstat output
-
sqlite_dbstatFTS5 Shadow Table Filtering — Now filters FTS5 shadow tables whenexcludeSystemTables: true- Previously
excludeSystemTablesonly filtered SpatiaLite system tables/indexes - Now also filters FTS5 shadow tables (
*_fts_data,*_fts_config,*_fts_docsize,*_fts_idx, etc.) - Applies to both summarize mode and raw page-level mode
- Previously
-
JSON Tool Naming Consistency — Renamed
sqlite_analyze_json_schematosqlite_json_analyze_schema- Aligns with the
sqlite_json_*prefix pattern used by all other tools in the JSON group - Updated ToolConstants.ts, ServerInstructions.ts, json-helpers.ts, and output-schemas.ts
- Aligns with the
-
ServerInstructions.ts Core Tools Documentation — Removed confusing
sqlite_list_viewsreference fromsqlite_list_tablesdescriptionsqlite_list_viewsis in the admin group, not core; reference was misleading in core tools table- Simplified description to: "List tables with column counts (excludeSystemTables hides SpatiaLite tables)"
-
Modern MCP SDK API Migration — Removed all
eslint-disablecommentsMcpServer.ts: Migrated built-in tools (server_info,server_health,list_adapters) from deprecatedserver.tool()toserver.registerTool()APISqliteAdapter.tsandNativeSqliteAdapter.ts: Migrated from deprecatedserver.resource()andserver.prompt()to modernserver.registerResource()andserver.registerPrompt()APIsmiddleware.ts: Replaced global namespace extension with proper Express module augmentation pattern (declare module "express-serve-static-core")progress-utils.ts: Replaced deprecatedServertype import with structural interface (NotificationSender)logger.ts: Replaced control character regex literals with dynamically constructedRegExpusingString.fromCharCode()to satisfyno-control-regexrule
-
sqlite_generate_seriesPure JS Implementation — Removed unnecessary native SQLite attempt- better-sqlite3's bundled SQLite lacks
SQLITE_ENABLE_SERIEScompile option - Native
generate_series()virtual table was always failing, wasting a database call - Now generates directly in JavaScript, eliminating the failed native attempt overhead
- better-sqlite3's bundled SQLite lacks
-
ServerInstructions.ts
sqlite_stats_top_nDocumentation — Strengthened payload optimization guidance- Changed comment from passive note to explicit
⚠️ warning: "Always use selectColumns to avoid returning all columns (large payloads with text fields)" - Emphasizes importance of column selection to reduce token usage
- Changed comment from passive note to explicit
-
sqlite_json_normalize_columnDefault Behavior — Changed defaultoutputFormatfromtexttopreserve- Prevents accidental JSONB-to-text conversion when normalizing columns that were previously converted to JSONB
- Use explicit
outputFormat: "text"when text output is specifically needed
-
ServerInstructions.ts
sqlite_json_eachPayload Warning — Added explicit warning about output row multiplication- Comment now reads: "Note: json_each multiplies output rows—use limit param for large arrays"
- Example updated to include
limit: 50parameter to demonstrate payload control
-
ServerInstructions.ts SpatiaLite Analyze Documentation — Improved tool documentation clarity
- Added explicit
analysisTypeoptions:spatial_extent | point_in_polygon | nearest_neighbor | distance_matrix - Documented
excludeSelfparameter for same-table nearest_neighbor/distance_matrix queries - Added note clarifying that distances are returned in Cartesian (degrees), not geodetic (km/miles)
- Added explicit
-
sqlite_drop_virtual_tableRegular Table Validation — Now validates target is actually a virtual table- Returns helpful error message if attempting to drop a regular table, directing to use
sqlite_drop_tableinstead - Prevents accidental misuse of virtual table drop tool on regular tables
- Returns helpful error message if attempting to drop a regular table, directing to use
-
sqlite_dbstatWASM Fallback Enhancement — Added table count to basic stats in WASM mode- When dbstat virtual table is unavailable, now returns
tableCountin addition topageCount - Provides more useful context about database contents
- When dbstat virtual table is unavailable, now returns
-
CSV Tool Messages WASM Clarity — Improved error messages for
sqlite_create_csv_tableandsqlite_analyze_csv_schema- When running in WASM mode, now explicitly states "CSV extension not available in WASM mode"
- Previously showed generic message about loading extension, which was misleading in WASM context
wasmLimitationflag is now dynamic based on actual runtime environment
-
ServerInstructions.ts CSV Documentation — Added WASM limitation note to CSV tool examples
- Comment now reads "Native only - not available in WASM" for clarity
-
ServerInstructions.ts
sqlite_list_tablesDocumentation — Clarified that views are listed viasqlite_list_views- Updated description to note that views require
sqlite_list_viewsfrom admin group
- Updated description to note that views require
-
sqlite_vector_searchPayload Optimization — Vector data now excluded from results when not explicitly requested- When
returnColumnsis specified without the vector column, results omit vector data for smaller payloads - Reduces response size significantly for high-dimensional vectors (e.g., 384+ dimensions)
- Vector data still included when
returnColumnsis empty or explicitly includes the vector column
- When
-
ServerInstructions.ts Vector Tool Documentation — Expanded vector section with all 11 tool examples
- Added missing tools:
sqlite_vector_batch_store,sqlite_vector_get,sqlite_vector_delete,sqlite_vector_count,sqlite_vector_dimensions - Added documentation note about
returnColumnspayload optimization
- Added missing tools:
-
ServerInstructions.ts Admin Tool Documentation — Expanded Database Administration section with all admin tool examples
- Added 20+ missing examples: views (
sqlite_create_view/drop_view/list_views), virtual tables, backup/restore/verify - Added PRAGMA utilities (
sqlite_pragma_compile_options/database_list/optimize),sqlite_index_stats,sqlite_dbstat - Added
sqlite_generate_series,sqlite_create_series_table,sqlite_create_rtree_table,sqlite_append_insight
- Added 20+ missing examples: views (
-
sqlite_pragma_database_listConfigured Path Visibility — AddedconfiguredPathfield to output- WASM mode shows internal virtual filesystem paths (e.g.,
/dbfile_3503536817) which can confuse users - Now includes
configuredPathshowing the user's original database file path - Adds explanatory
notewhen internal path differs from configured path
- WASM mode shows internal virtual filesystem paths (e.g.,
-
Dependency Updates — Updated npm dependencies to latest versions
@types/node: 25.1.0 → 25.2.0globals: 17.2.0 → 17.3.0pg: 8.17.2 → 8.18.0
-
ServerInstructions.ts FTS5 Documentation — Added note that FTS5 virtual tables and shadow tables are hidden from
sqlite_list_tablesfor cleaner output -
sqlite_fuzzy_matchToken-Based Matching — Now matches against word tokens by default instead of entire column value- New
tokenizeparameter (default:true) splits column values into words for per-token comparison - "laptop" now matches "Laptop Pro 15" (distance 0 on first token)
- Output includes
matchedTokenandtokenDistancefor transparency - Set
tokenize: falseto restore legacy behavior (match entire column value) - Removed full row data from output for token efficiency (just
valueand match info) - Updated
ServerInstructions.tsdocumentation with new behavior
- New
-
ServerInstructions.ts
generate_seriesDocumentation — Clarified JS fallback behavior- Changed WASM vs Native table entry from "✅ native | ❌ | JS" to "JS fallback | JS fallback | —"
- The generate_series extension is not compiled into SQLite, so both environments use the JavaScript fallback
-
sqlite_phonetic_matchDocumentation — Updated matching behavior description- Changed from "compares FIRST word only" to "matches against any word in value"
-
sqlite_json_keysDocumentation — Clarified distinct key behavior- Updated description to note tool returns unique keys across all matching rows, not per-row keys
-
ServerInstructions.ts Stats Group Documentation — Clarified window function grouping
- Line 70: Changed "Window functions (6 tools)" to "Window functions (6 tools in stats group)"
- Line 89: Changed "Stats(13-19)" to "Stats(19: 13 core + 6 window)" for clearer tool count breakdown
-
CSV Tools Path Validation — Improved error messages for
sqlite_create_csv_tableandsqlite_analyze_csv_schema- Now validates that file paths are absolute before attempting to create virtual table
- Returns helpful error message with suggested absolute path when relative path is provided
- Example:
"Relative path not supported. Please use an absolute path. Example: C:\\path\\to\\file.csv"
-
ServerInstructions.ts FTS5 Documentation — Fixed incomplete FTS5 example
- Added required
sqlite_fts_rebuildcall aftersqlite_fts_create(indexes are empty until rebuild) - Fixed parameter names:
table→tableName/sourceTableto match actual tool schema - Added clarifying comment explaining that triggers sync future changes but don't populate existing data
- Added required
-
sqlite_list_tablesDocumentation — Updated tool description in ServerInstructions.ts- Now mentions
excludeSystemTablesparameter for filtering SpatiaLite metadata
- Now mentions
-
ServerInstructions.ts SpatiaLite Tool Count — Improved documentation clarity
- Changed "SpatiaLite GIS (7 of 11 geo tools)" to "SpatiaLite GIS (7 tools; 4 basic geo always work)"
- Clarifies that 7 tools require SpatiaLite while 4 basic Haversine-based tools work in any mode
-
sqlite_json_normalize_columnJSONB Conversion Consistency — JSONB rows now always converted to normalized text format- Previously, JSONB rows with already-normalized content were left unchanged (still in JSONB binary format)
- Handler now detects original storage format and forces text output for all JSONB rows
- Ensures uniform text JSON format after normalization, avoiding mixed format scenarios
-
sqlite_stats_hypothesisChi-Square Validation — Added validation for insufficient categories- Chi-square test now throws descriptive error when df=0 (fewer than 2 categories in either column)
- Previously returned mathematically meaningless results (p=1, df=0) without warning
- Error message includes actual category counts for both columns to help users diagnose the issue
-
sqlite_json_storage_infoMixed Format Recommendation — Fixed misleading recommendation when column has both text and JSONB rows- Now detects mixed format scenarios and recommends running
sqlite_jsonb_convertto unify storage - Previously reported "Column already uses JSONB format" even when 50% of rows were still text JSON
- Now detects mixed format scenarios and recommends running
-
sqlite_spatialite_transformBuffer Auto-Simplification — Buffer operation now auto-simplifies output by default- Reduces verbose WKT payload from ~2KB (64-point circle) to ~200 bytes
- Default tolerance 0.0001 is suitable for lat/lon coordinates
- Set
simplifyTolerance: 0to disable auto-simplification for full precision output - Updated
ServerInstructions.tswith clarified documentation on distance parameter usage
-
sqlite_transaction_executeSELECT Row Data — SELECT statements now return actual row data- Results include
rowCountandrowsfields for SELECT statements instead of justrowsAffected: 0 - Enables read-modify-read patterns within atomic transactions
- Write statements continue to return
rowsAffectedas before
- Results include
-
sqlite_dbstatLimit Parameter — Added configurablelimitparameter (default: 100)- Controls maximum number of tables/pages returned in both summarized and raw modes
- Helps reduce payload size for large databases
- Previously hardcoded to 100; now user-configurable
-
sqlite_fuzzy_matchDocumentation — Clarified that Levenshtein distance is computed against entire column values- Updated description to note comparison is against whole values, not word tokens
- Added guidance to use maxDistance 1-3 for similar-length strings
- This is expected behavior; documentation now makes it explicit
-
sqlite_advanced_searchParameter Guidance — Added threshold tuning guidance forfuzzyThreshold- Parameter description now includes: "0.3-0.4 for loose matching, 0.6-0.8 for strict matching"
- Added inline example: "e.g., 'laptob' matches 'laptop'"
- Helps users understand how to tune the similarity threshold for their use case
-
ServerInstructions.ts Stats Tool Documentation — Added
selectColumnsexample forsqlite_stats_top_n- Documents payload optimization pattern for retrieving only required columns
- Helps reduce response size when querying tables with large text fields
-
ServerInstructions.ts Text Processing Documentation — Expanded TOOL_REFERENCE examples
- Added
sqlite_regex_extractexample with capture groups - Added
sqlite_text_split,sqlite_text_concat,sqlite_text_normalizeexamples - Added
sqlite_phonetic_matchexample with soundex algorithm - Clarified fuzzy match behavior: "compares against ENTIRE column value, not word tokens"
- Added
fuzzyThresholdtuning guidance comment insqlite_advanced_searchexample
- Added
-
sqlite_spatialite_analyzeSelf-Match Filtering — AddedexcludeSelfparameter (default: true)- When sourceTable equals targetTable in nearest_neighbor analysis, self-matches (distance=0) are now filtered
- Set
excludeSelf: falseto include self-matches in results - Reduces noise in proximity analysis results
-
sqlite_spatialite_transformBuffer Simplification — AddedsimplifyToleranceparameter- Optional simplification applied to buffer operation output to reduce vertex count
- Recommended values: 0.0001-0.001 for lat/lon coordinates
- Reduces payload size for large buffer polygons (96+ vertices → fewer)
-
sqlite_spatialite_analyzeDocumentation — Improved tool description- Clarified that point_in_polygon requires POINTs in sourceTable and POLYGONs in targetTable
- Updated targetTable parameter description with geometry type guidance
-
ServerInstructions.ts Vector Tool Documentation — Expanded vector section with utility tool examples
- Added
sqlite_vector_normalize,sqlite_vector_distance, andsqlite_vector_statsexamples - Utility tools help with pre-processing embeddings before storage
- Added
-
sqlite_text_splitPer-Row Output Structure — Improved output for row traceability- Changed from flat
parts[]array to structured per-row results - Each row now includes
rowid,originalvalue, andpartsarray - Enables correlation between split results and source rows
- Changed from flat
-
ServerInstructions.ts WASM Tool Count — Corrected
starterpreset count for WASM mode- Changed from 48 to 44 (4 FTS5 tools unavailable in WASM)
- Added footnote: "17 = 13 in WASM (4 FTS5 tools require native)"
-
ServerInstructions.ts JSONB Documentation — Added note that
sqlite_json_normalize_columnconverts JSONB back to text format- The
json()function used for normalization returns text JSON, not JSONB binary - Users should run
sqlite_jsonb_convertafter normalization if JSONB format is desired
- The
-
ServerInstructions.ts Text Processing Documentation — Added inline comment for regex escaping clarity
- Explains that regex patterns require double-escaping backslashes (
\\\\) when passing through JSON/MCP transport
- Explains that regex patterns require double-escaping backslashes (
-
ServerInstructions.ts CSV Path Documentation — Added absolute path requirement note for CSV tools
- Updated WASM vs Native table: CSV virtual tables now note "(requires absolute paths)"
- Added CSV Virtual Tables examples to Database Administration section showing
sqlite_analyze_csv_schemaandsqlite_create_csv_tablewith absolute path usage
-
ServerInstructions.ts Statistical Analysis Examples — Added missing stats tool examples to TOOL_REFERENCE
- Added
sqlite_stats_outliersexample with IQR/Z-score method options - Added
sqlite_stats_hypothesisexample with one-sample t-test usage
- Added
-
JSON Aggregation Tool Documentation — Clarified
groupByColumnusage for JSON collection tables- Updated
sqlite_json_group_arrayandsqlite_json_group_objectparameter descriptions - For JSON collections, must use
allowExpressions: truewithjson_extract(data, '$.field')for groupByColumn - Updated ServerInstructions.ts examples to show both regular table and JSON collection patterns
- Updated
-
Tool Count Documentation Accuracy — Fixed tool counts across all documentation files
textgroup: 16 → 17 (added fuzzy_match, phonetic_match, text_normalize, text_validate, advanced_search, fts_rebuild, fts_match_info)admingroup: 32 → 33starterpreset: 47 → 48searchpreset: 35 → 36fullpreset: 120 → 122 Native, 100 → 102 WASM- Updated ToolConstants.ts, ServerInstructions.ts, and README.md
-
ServerInstructions.ts Text Processing Examples — Updated TOOL_REFERENCE section
- Fixed
sqlite_fuzzy_searchexample to correct tool namesqlite_fuzzy_matchwith proper parameters - Replaced generic
sqlite_text_similarityexample with practicalsqlite_text_validate(email/phone/url/uuid/ipv4) - Added
sqlite_advanced_searchexample demonstrating multi-technique search (exact/fuzzy/phonetic)
- Fixed
-
ServerInstructions.ts Documentation Improvements — Updated tool filtering reference for accuracy
- Corrected tool counts to match README (was showing outdated single-column counts)
- Added WASM/Native columns to shortcut table showing accurate counts per backend
- Added
spatialshortcut (23 WASM / 30 Native tools) - Added
geoto groups list (was missing from documentation) - Added Fallback column to WASM vs Native table documenting JS fallback availability
- Documented
generate_series,dbstat,soundexJS fallbacks vs extension tools with no fallback - Added Database Administration examples section with 6 common admin tools
-
WASM Mode FTS5 Graceful Handling — FTS5 tools now return helpful errors instead of crashes in WASM mode
- All 4 FTS5 tools (
sqlite_fts_create,sqlite_fts_search,sqlite_fts_rebuild,sqlite_fts_match_info) detect "no such module: fts5" errors - Returns structured error with
hintdirecting to native SQLite backend (--sqlite-native) - Prevents tool failures when running in WASM mode (sql.js) which lacks FTS5 module
- All 4 FTS5 tools (
-
WASM Mode Soundex Fallback —
sqlite_phonetic_matchnow works with soundex algorithm in WASM mode- JavaScript-based soundex implementation used as fallback when SQLite's native
soundex()function unavailable - Behavior matches metaphone algorithm path (fetch rows, filter in JS)
- Same output format and accuracy as native soundex
- Gracefully handles "no such function: soundex" error without user intervention
- JavaScript-based soundex implementation used as fallback when SQLite's native
-
SQLite-Focused Branding — Updated project descriptions to reflect SQLite-only focus
package.json: Updated description and removed unused database keywords (postgresql, mysql, mongodb, redis)src/cli.ts: Updated help text, removed dead CLI options and environment variable parsing for unsupported databases- Updated header comments in
src/index.ts,src/server/McpServer.ts,src/adapters/DatabaseAdapter.ts
-
Simplified SpatiaLite Instructions — Removed manual
sqlite_spatialite_loadstep requirement- SpatiaLite extension and metadata tables are now auto-initialized on first use of any spatial tool
- Removed "IMPORTANT" warning and step numbering from
ServerInstructions.ts - Added GeoJSON import example to instructions
-
Node.js 24 LTS Baseline — Upgraded from Node 20 to Node 24 LTS as the project baseline
package.jsonnow requires Node.js >=24.0.0 inenginesfield- README prerequisites updated to specify Node.js 24+ (LTS)
@modelcontextprotocol/sdk: 1.24.3 → 1.25.3@types/node: 25.0.2 → 25.1.0better-sqlite3: 12.5.0 → 12.6.2cors: 2.8.5 → 2.8.6globals: 16.5.0 → 17.2.0 (major version bump)pg: 8.16.3 → 8.17.2typescript-eslint: 8.49.0 → 8.54.0vitest: 4.0.15 → 4.0.18zod: 4.1.13 → 4.3.6
-
OAuth 2.1 Implementation — Tested with Keycloak 26.4.7
- Token validation with JWKS endpoint verified
- Scope enforcement (
read,write,admin) working correctly - RFC 9728 Protected Resource Metadata endpoint operational
- Added OAuth Quick Start section to README with usage examples
-
sqlite_vector_searchreturnColumns Consistency — FixedreturnColumnsbeing ignored for euclidean/dot metrics- Previously,
returnColumnsonly filtered output when using cosine similarity; euclidean and dot returned all columns - Now consistently applies column filtering after similarity calculation for all three metrics
- Reduces payload size for non-cosine searches (previously ~3x larger due to full embedding vectors in output)
- Previously,
-
sqlite_backupWASM Consistent Error Response — Backup now returnssuccess: falseupfront in WASM mode- Previously, backup attempted
VACUUM INTOthen caught errors, leading to inconsistent behavior: sometimes succeeding to ephemeral VFS, sometimes failing on path resolution - Now checks
isNativeBackend()first and returns{success: false, wasmLimitation: true}immediately - Consistent with
sqlite_restoreandsqlite_verify_backupwhich already had upfront WASM checks - Native mode behavior unchanged: backup still uses
VACUUM INTOand returns structured errors on failure
- Previously, backup attempted
-
Stats Tool Group Bug Fixes — Resolved 6 issues from comprehensive tool testing
sqlite_stats_histogram: Fixed off-by-one bucket boundary that excluded max values (now uses<=for final bucket)sqlite_stats_summary: Auto-filters to numeric columns when no columns specified (prevents string min/max errors)sqlite_stats_correlation: Returnsnullinstead ofNaNfor invalid correlations (schema-safe)sqlite_stats_hypothesis: Validates t-statistic is finite before returning (catches zero variance/non-numeric columns)sqlite_stats_basic: Ensures numeric type coercion for all stat values (converts strings to numbers or null)sqlite_stats_group_by: Validates bothvalueColumnandgroupByColumnexist in table before execution
-
NativeSqliteAdapter Missing Method — Added
getConfiguredPath()to match SqliteAdapter interfacesqlite_pragma_database_listtool was failing in native mode due to missing method- Now returns configured database path consistently across WASM and Native adapters
-
sqlite_dbstatTable-Specific WASM Fallback — Improved fallback when dbstat virtual table unavailable- Previously, the
tableparameter was ignored in WASM mode, returning only total database page count - Now provides table-specific estimates:
rowCount,estimatedPages(~100 rows/page), andtotalDatabasePages - Returns
success: falsewith appropriate message if specified table doesn't exist
- Previously, the
-
sqlite_drop_virtual_tableAccurate Messaging — Fixed misleading success message for non-existent tables- Previously, dropping a non-existent table with
ifExists: truereported "Dropped virtual table 'x'" - Now returns accurate message: "Virtual table 'x' did not exist (no action taken)"
- Helps distinguish between actual drops and no-op operations
- Previously, dropping a non-existent table with
-
FTS5 Tools WASM Upfront Check —
sqlite_fts_search,sqlite_fts_rebuild,sqlite_fts_match_infonow check FTS5 availability upfront- Previously, these tools threw raw "no such table" SQL errors in WASM mode when FTS tables couldn't be created
- Now return graceful error response with hint before attempting any SQL execution
- Consistent with
sqlite_fts_createwhich already had upfront FTS5 detection
-
WASM Adapter Templated Resource Support — Fixed
sqlite://table/{name}/schemaresource returning "not found" in WASM mode- Ported
ResourceTemplatehandling fromNativeSqliteAdaptertoSqliteAdapter - Templated resources now properly register with MCP SDK's
ResourceTemplateclass - Both static and templated resources now work consistently across WASM and Native backends
- Ported
-
Index Column Population in WASM Adapter — Fixed
sqlite://indexesresource returning emptycolumnsarray- Added
PRAGMA index_info()queries to populate column names for each index - Updated both
SchemaManager.getAllIndexes()andSqliteAdapter.getIndexes()fallback - Index metadata now matches Native adapter behavior
- Added
-
sqlite_list_tablesKNN2 Virtual Table — KNN2 SpatiaLite virtual table now filtered byexcludeSystemTables- Added "KNN2" to the SpatiaLite system table exclusion list
- Previously KNN2 was shown despite
excludeSystemTables=true
-
sqlite_json_group_objectAggregate Function Support — NewaggregateFunctionparameter for aggregate values- Enables
COUNT(*),SUM(amount),AVG(price), and other aggregate functions as object values - Uses subquery pattern to pre-aggregate results before wrapping in
json_group_object() - Example:
sqlite_json_group_object({ table: "events", keyColumn: "event_type", aggregateFunction: "COUNT(*)" }) allowExpressionsparameter clarified: supports column extraction only, NOT aggregate functions- New: Returns
hintwarning when usingallowExpressionswithoutgroupByColumn(duplicate keys may result if key values aren't unique)
- Enables
-
server_healthSpatiaLite Status — Health check now reports accurate SpatiaLite extension status- Previously hardcoded
spatialite: falseregardless of actual extension state - Now calls exported
isSpatialiteLoaded()to reflect runtime extension status - Helps users confirm SpatiaLite is loaded before using spatial tools
- Previously hardcoded
-
sqlite_text_splitWASM Rowid Bug — Fixed rows returningrowid: 0for all results- Changed SQL query from
SELECT rowid, columntoSELECT rowid as id, columnfor consistent behavior - SQL.js (WASM) does not handle unaliased
rowidcolumn correctly; aliasing ensures proper value retrieval - Native SQLite (better-sqlite3) was unaffected, but now uses consistent query pattern
- Changed SQL query from
-
sqlite_list_tablesFTS5 Table Visibility — FTS5 virtual tables and shadow tables now hidden- Virtual tables ending with
_fts(e.g.,articles_fts) are now filtered from output - Shadow tables containing
_fts_(e.g.,articles_fts_config,articles_fts_data) already filtered - Internal FTS5 implementation details no longer clutter table listings in native mode
- Virtual tables ending with
-
sqlite_text_validateNull Value Display — Improved accuracy for invalid null/empty values- Null/undefined values now display as
nullinstead of artificial"(empty)"placeholder - Long values (>100 chars) are truncated with "..." for readability
- Null/undefined values now display as
-
sqlite_json_group_arrayandsqlite_json_group_objectgroupByColumn Expressions — ExtendedallowExpressionsto also apply togroupByColumnparameter- Previously
allowExpressions: trueonly bypassed validation forvalueColumn/keyColumn, notgroupByColumn - Now enables grouping by JSON path expressions like
json_extract(data, '$.type') - When using expressions for
groupByColumn, output usesgroup_keyalias for clarity
- Previously
-
sqlite_json_group_arrayExpression Support — AddedallowExpressionsoption for consistency withsqlite_json_group_object- When
allowExpressions: true, SQL expressions likejson_extract(data, '$.name')are accepted forvalueColumn - Default behavior unchanged (validates as simple column identifier for security)
- Enables advanced aggregation patterns combining JSON extraction with grouping
- When
-
sqlite_json_updateString Value Escaping — Fixed "malformed JSON" error when updating string values- String values now wrapped with
JSON.stringify()before SQL escaping to produce valid JSON - Previously
'New Title'(invalid JSON) was passed tojson()instead of'"New Title"'
- String values now wrapped with
-
sqlite_spatialite_analyzeError Message Clarity — Improved error messages for required parameter validation- Changed "Target table required" to "Missing required parameter 'targetTable'" for
nearest_neighborandpoint_in_polygonanalysis types - Clearer messaging helps users identify which parameter they need to provide
- Changed "Target table required" to "Missing required parameter 'targetTable'" for
-
sqlite_json_group_arrayandsqlite_json_group_objectColumn Naming — Fixed quoted identifier names appearing in output- When using
groupByColumn, the result column was showing"type"(with escaped quotes) instead oftype - Added explicit column aliases (e.g.,
"type" AS type) to produce clean column names in output - Affects both tools when
groupByColumnis specified
- When using
-
sqlite_dbstatPage Count Inconsistency — Fixed JS fallback returning inconsistent page counts- Properly extracts page_count from PRAGMA result (handles both named and indexed column access)
- Ensures consistent numeric return value via explicit type coercion
-
False WASM Limitation Detection in Native Mode — Fixed backup/restore/verify tools incorrectly reporting WASM limitations when running in native mode
- Added
isNativeBackend()method to bothSqliteAdapter(returns false) andNativeSqliteAdapter(returns true) sqlite_backup,sqlite_restore,sqlite_verify_backupnow only returnwasmLimitation: truewhen actually running in WASM modesqlite_restorenow attempts to recreate virtual tables (FTS5, R-Tree) in native mode instead of unconditionally skipping them- In native mode, actual file system errors are now properly thrown instead of being masked as WASM limitations
- Added
-
sqlite_create_tableSQL Expression Default Values — Fixed syntax error when using SQL expressions as default values- Expressions like
datetime('now'),CURRENT_TIMESTAMP,CURRENT_DATE,CURRENT_TIMEnow wrapped in parentheses - Literal string values continue to be properly single-quoted with escape handling for embedded quotes
- Added regex detection for function calls (pattern
function_name(...)) and SQL keywords
- Expressions like
-
JSONB Normalize Corruption Fix — Fixed
sqlite_json_normalize_columncorrupting JSONB columns- Changed query to use
json(${column})SQL function to convert JSONB binary to text before JavaScript processing - Previously, JSONB binary blobs were being serialized as numbered-key objects (
{"0":204,"1":95,...}) - Now properly handles both text JSON and JSONB binary format without data loss
- Changed query to use
-
ServerInstructions.ts Core Tools Table — Added missing tools to documentation
- Added
sqlite_drop_tableandsqlite_get_indexesto Core Tools table (was only showing 6 of 8 tools)
- Added
-
WASM Mode Admin Tool Graceful Handling — 4 admin tools now return structured errors instead of throwing in WASM mode
sqlite_virtual_table_info: ReturnsmoduleAvailable: falsewith partial metadata when module unavailable (e.g., FTS5)sqlite_backup: ReturnswasmLimitation: truewhen file system access unavailablesqlite_restore: ReturnswasmLimitation: truewhen file system access unavailablesqlite_verify_backup: ReturnswasmLimitation: truewhen file system access unavailable- Added
wasmLimitationfield toBackupOutputSchema,RestoreOutputSchema,VerifyBackupOutputSchema - Updated
ServerInstructions.tsWASM vs Native table with backup/restore, R-Tree, CSV limitations
-
Restore Tool Security Bypass —
sqlite_restorenow bypasses SQL validation for internal operations- Added
skipValidationoptional parameter toexecuteWriteQuery()method signature - Internal restore operations (ATTACH, DROP, CREATE, INSERT, DETACH, PRAGMA) pass
skipValidation=true - Prevents false-positive "dangerous patterns" errors from internal SQL comments or multi-statement patterns
- Security remains intact: bypass only applies to trusted internal operations, not user-provided queries
- Added
-
WASM Mode R-Tree/CSV/Restore Graceful Handling — 4 additional admin tools now return structured errors instead of throwing
sqlite_create_rtree_table: Returnssuccess: falsewithwasmLimitation: truewhen R-Tree module unavailablesqlite_analyze_csv_schema: Returnssuccess: falsewithwasmLimitation: truewhen CSV extension not loadedsqlite_create_csv_table: Returnssuccess: falsewithwasmLimitation: truewhen CSV extension not loadedsqlite_restore: Now skips virtual tables with unavailable modules (FTS5, R-Tree) instead of failing entire restore- Added
skippedTablesandnotefields toRestoreOutputSchemafor partial restore reporting
-
SpatiaLite Analyze WKT Output — Fixed
sqlite_spatialite_analyzebinary geometry outputnearest_neighborandpoint_in_polygonanalysis types now return WKT viaAsText()instead of raw binary blobs- Changed from
s.*wildcard select to explicitsource_id,source_geom,target_id,target_geomcolumns - Reduces payload size and improves readability (binary arrays → human-readable WKT strings)
-
Restore Virtual Table Handling — Fixed
sqlite_restorefailing with virtual table shadow tables- Added pre-restore phase to drop existing virtual tables before attempting restore
- Virtual table deletion automatically cleans up associated shadow tables (R-Tree:
_node,_rowid,_parent) - Excludes R-Tree shadow tables from copy list in addition to FTS5 shadow tables
- Prevents "may not be dropped" error when backup contains virtual table artifacts
-
Custom Regex Validation Double-Escaping Fix — Fixed
sqlite_text_validatecustom pattern handling- Normalizes double-escaped backslashes (
\\\\→\\) from JSON transport - Patterns like
.*@.*\.com$now work correctly as expected - Added error message with both original and normalized pattern for debugging invalid regex
- Normalizes double-escaped backslashes (
-
JSON Each Ambiguous Column Fix — Fixed
sqlite_json_each"ambiguous column name: id" error- Added table alias (
t) andCROSS JOINsyntax to prevent column name conflicts withjson_each()TVF output json_each()returns columns:key,value,type,atom,id,parent,fullkey,path- Source table columns (especially
id) now properly qualified with table alias - Added automatic
id =→t.id =rewriting for user-provided WHERE clauses - Updated
JsonEachOutputSchemato include optionalrow_idfield for row identification
- Added table alias (
-
JSON Group Object Expression Support — Added
allowExpressionsoption tosqlite_json_group_object- When
allowExpressions: true, SQL expressions likejson_extract(data, '$.name')are accepted forkeyColumnandvalueColumn - Default behavior unchanged (validates as simple column identifiers for security)
- When
-
JSONB Text Serialization Fix — Fixed
sqlite_json_selectreturning binary Buffer for JSONB data- Wrapped column selection with
json()function to convert JSONB binary to readable text JSON - Works seamlessly with both text JSON (no-op) and JSONB (converts to text)
- API consumers now receive readable JSON instead of raw binary buffers
- Wrapped column selection with
-
JSONB Schema Analysis Fix — Fixed
sqlite_analyze_json_schemareturning byte indexes for JSONB columns- Wrapped column with
json()function to decode JSONB binary before schema inference - Was returning numeric keys (0, 1, 2, ..., 100) representing blob bytes instead of actual JSON structure
- Now correctly infers object properties, types, and nullability for JSONB-formatted data
- Wrapped column with
-
Core Tool Bug Fixes — Resolved 3 issues discovered during comprehensive MCP tool testing
sqlite_describe_tablenow correctly returns an error for non-existent tables (was returningsuccess: truewith empty columns)sqlite_write_queryand other query methods now auto-convert boolean parameters (true/false) to integers (1/0) since SQLite doesn't have native boolean typesqlite_create_tablemessage now accurately indicates when table already exists (using IF NOT EXISTS): "Table 'x' already exists (no changes made)"sqlite_list_tablesnow correctly returnscolumnCountfor each table (was always returning 0 in native adapter becausePRAGMA table_info()was not being called)
-
JSON Path Column Naming — Fixed column naming in
json_selectandjson_querytools- Columns now use meaningful names extracted from JSONPath expressions (e.g.,
$.user.email→email) - Was returning generic indexed names (
path_0,result_0) - Added
extractColumnNameFromPath()andgetUniqueColumnNames()helpers injson-helpers.ts - Duplicate path segments get numeric suffixes (e.g.,
name,name_2)
- Columns now use meaningful names extracted from JSONPath expressions (e.g.,
-
Text Tool Output Schema Fixes — Fixed 6 tools with output validation errors
sqlite_regex_extract: Added safe rowid coercion (Number/String/undefined → Number) to prevent NaN in outputsqlite_regex_match: Added safe rowid coercion (Number/String/undefined → Number) to prevent NaN in outputsqlite_text_split: ChangedrowCount/resultstoparts/countto match schemasqlite_advanced_search: Fixed NaN bug when coercing rowid to numbersqlite_fts_create: ChangedsqltotableNamein response to match schemasqlite_fts_rebuild: Added missingtableNamefield to response
-
Text Tool Bug Fixes — Resolved issues discovered during comprehensive MCP tool testing
sqlite_text_concat: Fixed SQL generation to use||operator for concatenation (was generating comma-separated SELECT which only returns last column)sqlite_regex_extract,sqlite_regex_match,sqlite_advanced_search: Fixed rowid extraction by aliasingrowid as idin SQL queries (was returning 0 for all rows)sqlite_phonetic_match: Fixed emptysearchCodefor soundex algorithm by computing locally upfront (was only extracting from matches, returning empty when no matches found)
-
Test Database FTS5 Table — Added pre-built FTS5 table for testing
test_articles_fts: FTS5 virtual table indexingtest_articles(title, body)- Updated
test-database.sqlto create and populate the FTS index - Updated
reset-database.mddocumentation with new table
-
JSONB Support in Native Adapter — Fixed JSONB detection missing in
NativeSqliteAdapterNativeSqliteAdapter.connect()now detects SQLite version and sets JSONB support flagsqlite_jsonb_convertand other JSONB tools now work correctly with better-sqlite3 backend- better-sqlite3 includes SQLite 3.51.2 which fully supports JSONB (requires 3.45+)
-
JSONB-Compatible Collection Tables — Updated
sqlite_create_json_collectionCHECK constraint- Changed from
CHECK(json_valid("data"))toCHECK(json_type("data") IS NOT NULL) json_valid()only works on text JSON;json_type()works on both text and JSONB formats- Collections can now store JSONB data after
sqlite_jsonb_convert
- Changed from
-
JSON Tool Output Schema Fixes — Fixed 6 tools with output validation errors
sqlite_json_keys: Added missingrowCountfield and fixedkeysarray typesqlite_json_group_array: Changedresultstorowsto match schemasqlite_json_group_object: Changedresultstorowsto match schemasqlite_jsonb_convert: Created dedicatedJsonbConvertOutputSchemasqlite_json_storage_info: Created dedicatedJsonStorageInfoOutputSchemasqlite_json_normalize_column: Created dedicatedJsonNormalizeColumnOutputSchema- Added
JsonPrettyOutputSchemaforsqlite_json_pretty - Updated
ToolConstants.tswith correct list of all 23 JSON tool names
-
Stats Tool Output Schema Fixes — Fixed 8 tools with output validation errors
- Created dedicated output schemas:
StatsBasicOutputSchema,StatsCountOutputSchema,StatsGroupByOutputSchema,StatsTopNOutputSchema,StatsDistinctOutputSchema,StatsSummaryOutputSchema,StatsFrequencyOutputSchema - Updated
StatsPercentileOutputSchemato support array of percentiles (was single value) - Updated
StatsHistogramOutputSchemawith optionalrange,bucketSize, andbucketfields - Updated
StatsCorrelationOutputSchemawith optionalnandmessagefields - Tools fixed:
sqlite_stats_basic,sqlite_stats_count,sqlite_stats_group_by,sqlite_stats_percentile,sqlite_stats_top_n,sqlite_stats_distinct,sqlite_stats_summary,sqlite_stats_frequency
- Created dedicated output schemas:
-
Vector Tool Output Schema Fixes — Fixed 10 tools with output validation errors
- Created dedicated output schemas:
VectorStoreOutputSchema,VectorBatchStoreOutputSchema,VectorGetOutputSchema,VectorDeleteOutputSchema,VectorCountOutputSchema,VectorStatsOutputSchema,VectorDimensionsOutputSchema,VectorNormalizeOutputSchema,VectorDistanceOutputSchema - Updated
VectorSearchOutputSchemato match handler return structure (metric,count,resultswith_similarity) - Tools fixed:
sqlite_vector_store,sqlite_vector_batch_store,sqlite_vector_get,sqlite_vector_search,sqlite_vector_delete,sqlite_vector_count,sqlite_vector_stats,sqlite_vector_dimensions,sqlite_vector_normalize,sqlite_vector_distance
- Created dedicated output schemas:
-
Admin Tool Bug Fixes — Fixed 4 tools with output schema and logic errors
sqlite_create_view: Fixed syntax error by using DROP+CREATE pattern (SQLite doesn't supportCREATE OR REPLACE VIEW)sqlite_list_views: Created dedicatedListViewsOutputSchema(was usingListTablesOutputSchemaexpectingtablesinstead ofviews)sqlite_optimize: Added requiredmessagefield to handler return objectsqlite_restore: Fixed PRAGMA query that caused "no such table: 1" error (simplified toPRAGMA integrity_check(1))
-
Geo Tool Output Schema Fixes — Fixed 3 tools with output validation errors
sqlite_geo_nearby: Changedcountfield torowCount, removed extra metadata fieldssqlite_geo_bounding_box: Changedcountfield torowCount, removed extra metadata fieldssqlite_geo_cluster: Restructured return to match schema withclusterId,center: {latitude, longitude},pointCount
-
SpatiaLite Windows DLL Loading — Fixed extension loading on Windows
- Added runtime PATH modification to prepend SpatiaLite directory before
loadExtension()call - Windows requires dependency DLLs (libgeos, libproj, etc.) to be discoverable via PATH
- Applied to both
NativeSqliteAdapter.ts(startup) andspatialite.ts(on-demand loading) - Following pattern from Python sqlite-mcp-server implementation
- Added runtime PATH modification to prepend SpatiaLite directory before
-
SpatiaLite Tool Bug Fixes — Fixed 3 tools that silently failed due to incorrect method usage
sqlite_spatialite_create_table: ChangedexecuteWriteQuerytoexecuteReadQueryforAddGeometryColumn()callsqlite_spatialite_index(create/drop): Changed toexecuteReadQueryforCreateSpatialIndex()andDisableSpatialIndex()calls- Root cause: better-sqlite3's
.run()method only works for INSERT/UPDATE/DELETE, not SELECT statements - Added verification step after geometry column creation to ensure column exists before reporting success
- Cascading fix enables
sqlite_spatialite_importandsqlite_spatialite_analyzeto work correctly
-
SpatiaLite Metadata Initialization — Fixed missing
geometry_columnstable on pre-loaded databasesisSpatialiteLoaded()now callsInitSpatialMetaData(1)when detecting a pre-loaded SpatiaLite extension- Ensures SpatiaLite metadata tables (
geometry_columns,spatial_ref_sys) exist even if extension was loaded in previous session - Fixes
sqlite_spatialite_analyze"no such table: geometry_columns" error - Fixes
sqlite_spatialite_create_tablereturning 0 fromAddGeometryColumn()call
-
SpatiaLite GeoJSON Import Fix — Fixed SRID constraint violation when importing GeoJSON data
- Wrapped
GeomFromGeoJSON()withSetSRID(..., srid)to ensure SRID is set correctly - GeoJSON import now supports
additionalDatacolumns (was only available for WKT import) - Fixes "geom violates Geometry constraint [geom-type or SRID not allowed]" error
- Wrapped
-
MCP SDK 1.25.2 Compatibility — Fixed stricter transport type requirements
- Added onclose handler to StreamableHTTPServerTransport before connecting
- Used type assertion to satisfy SDK's narrower Transport type constraints
-
Identifier Validation Centralization — Migrated 83 tool handlers to use centralized
sanitizeIdentifier()utility- Replaced inline regex validations with type-safe
InvalidIdentifierErrorhandling - Consistent security pattern across 10 files:
geo.ts,admin.ts,text.ts,vector.ts,virtual.ts,stats.ts,fts.ts,json-operations.ts,json-helpers.ts,core.ts - Updated security tests to expect new error message format
- Replaced inline regex validations with type-safe
-
Transitive Dependency Fixes — Resolved vulnerabilities via npm audit fix
hono: 4.11.5 → 4.11.7 (moderate severity fix via@modelcontextprotocol/sdk)
-
Log Injection Prevention — Control character sanitization for log messages
- Strips all ASCII control characters (0x00-0x1F) and DEL (0x7F) from messages
- Prevents log forging and escape sequence attacks
- Dedicated
sanitizeStack()function replaces newlines with arrow delimiters for safe stack trace logging
-
Sensitive Data Redaction — Automatic redaction of security-sensitive fields in log context
- Sensitive keys redacted: password, secret, token, authorization, apikey, access_token, refresh_token, credential, client_secret
- OAuth 2.1 fields redacted: issuer, audience, jwks_uri, oauth_config, scopes_supported, bearer_format
- Supports recursive sanitization for nested configuration objects
- Prevents exposure of OAuth configuration data in log output
-
CodeQL Taint Tracking Fix — Resolved static analysis alerts in logger
- Fixed
js/clear-text-loggingby breaking data-flow path inwriteToStderr() - Fixed
js/log-injectionby reconstructing output from static character codes - Implemented the "Static Classification" pattern for taint-breaking sanitization
- Fixed
-
SQL Injection Protection — WHERE clause validation and identifier sanitization (adapted from postgres-mcp)
- New
src/utils/where-clause.tsutility with SQLite-specific dangerous pattern detection - Blocks: ATTACH DATABASE, load_extension, PRAGMA, fileio functions, hex literals, comments, UNION attacks
- New
src/utils/identifiers.tswith centralized identifier validation and quoting - Integrated
validateWhereClauseinto 36 tool handlers (text, window, vector, stats, geo) - New
tests/security/security-injection.test.tstest suite (49 comprehensive test cases) - New
tests/security/tool-integration.test.tstest suite (67 end-to-end handler tests)
- New
-
Handler Security Hardening — Added missing WHERE clause validation to tool handlers
geo.ts: AddedvalidateWhereClause()tosqlite_geo_clusterstats.ts: AddedvalidateWhereClause()tosqlite_stats_outliers,sqlite_stats_top_n,sqlite_stats_distinct,sqlite_stats_frequency