Skip to main content

Module engine

Module engine 

Source
Expand description

Core database engine that owns the HyperProcess and its connection.

The Engine is the single point of contact with the Hyper database. It manages process startup, connection lifecycle, table DDL, query execution, and workspace metadata. All higher-level modules (ingest, export, server) operate through an &Engine reference.

§Lazy Initialization and Connection Recovery

The engine is lazily initialized by crate::server::HyperMcpServer on the first tool call (not during MCP handshake). This keeps the initialize response fast and avoids starting hyperd if the client never calls a tool.

If the connection to hyperd is lost (crash, broken pipe, wire-protocol desync), the server’s crate::server::HyperMcpServer::with_engine wrapper detects the crate::error::ErrorCode::ConnectionLost error, drops the engine, and transparently re-creates it on the next call. This auto-reconnect path covers both transport-level failures and the "desynchronized" state surfaced by the hyper-client layer’s bounded drain.

§Workspace Model

Every session has an ephemeral primary database at $TMPDIR/hyperdb-mcp-<pid>/scratch.hyper. This is where unqualified tool calls land — exploratory loads, ad-hoc queries, scratch tables. It is created fresh on engine start and deleted (DETACH + remove) when the engine drops.

When a persistent path is supplied (CLI --persistent-db, env var HYPERDB_PERSISTENT_DB, or the platform default), the engine records it; the crate::server::HyperMcpServer then ATTACHes that file under alias "persistent" after construction so the LLM can target it via the database parameter on data tools, or via persist: true on load tools. The persistent file lives across sessions.

Passing None (or --ephemeral-only at the CLI) skips the persistent attachment; the only available database is the ephemeral primary plus any user-attached DBs.

§Sync Calls in an Async Server

All Engine methods are synchronous (blocking). The MCP server runs on a tokio runtime, but hyperd communication goes through the hyperdb-api crate’s blocking Connection API. The rmcp framework spawns tool handlers on its own task pool, so blocking calls do not starve the async event loop. A future optimization could use spawn_blocking or an async connection API, but the current approach is correct and simple.

Structs§

Engine
The connection is bound to the ephemeral primary at Self::ephemeral_path. Unqualified SQL routes here.When Self::persistent_path is Some, the server attaches that file as "persistent" after engine construction. When None, no persistent storage is available this session (--ephemeral-only).
PersistentAttachOutcome
Outcome of [attach_default_persistent] — flags whether the file was freshly created so the catalog-seed step can fire (or skip).
ScopedSearchPath
Owns a connection to hyperd, the ephemeral primary database, and an optional persistent attachment path. All SQL execution flows through this struct.

Enums§

StatementKind
Coarse classification of a single SQL statement, comment-aware.

Constants§

CLIENT_LOG_FILE_NAME
Name of the client-side log file written in resolve_log_dir. The MCP binary’s main opens this file and sets it as a tracing subscriber target so both startup errors and runtime events land here.
HYPERDB_INTERNAL_PREFIX
Name-prefix convention for tables that belong to the HyperDB MCP’s own infrastructure (currently the _hyperdb_saved_queries meta-table used by WorkspaceStore). Hidden from Engine::describe_tables and from Engine::status’s table_count / total_rows, so users never see HyperDB’s own bookkeeping in the public catalog.

Functions§

classify_statement
Coarse-classify the first SQL statement in sql after stripping leading whitespace and line/block comments.
is_internal_table
Returns true when name is one of HyperDB’s own internal tables (matches HYPERDB_INTERNAL_PREFIX). Factored into a helper so every filter site calls the same predicate and a future move to a more nuanced scheme (e.g. per-table allowlist) is a single edit.
is_read_only_sql
Returns true if a SQL statement is read-only: SELECT, WITH, EXPLAIN, SHOW, or VALUES. Anything else (CREATE, INSERT, UPDATE, DELETE, DROP, ALTER, COPY, …) is considered mutating.
resolve_log_dir
Compute the log directory for both hyperd output and the client-side tracing log. Shared by Engine::new and main so both land in the same place.