How DBX Detects Database Capabilities Dynamically at Runtime
DBX discovers driver capabilities through a lightweight JSON-RPC handshake performed immediately after the agent process starts, enabling runtime adaptation without client rebuilds.
DBX (Database eXplorer) implements a dynamic capability detection system that allows the core client to adapt to different database drivers at runtime. Rather than hardcoding supported operations, the system performs a protocol handshake through a JSON-RPC channel to determine what each driver can execute. This architecture lets the t8y2/dbx project add new database features by updating only the agent code, with the client automatically respecting the advertised capability set on the next connection.
The Handshake Protocol: Core Mechanism for Capability Detection
The capability detection relies on a handshake method exchanged over the JSON-RPC channel immediately after the agent process launches. This single request-response cycle establishes the entire API surface available for that session.
Agent-Side Implementation
Each database driver implements the handshake within its dispatch function, returning a hardcoded JSON object that declares supported operations. The method signature accepts a method name and parameters map, then returns the capability list along with protocol version information.
In agents/drivers/xugu/main.go and agents/drivers/oracle-go/main.go, the implementation follows this pattern:
func (s *server) dispatch(method string, params map[string]json.RawMessage) (any, bool, error) {
switch method {
case "handshake":
return map[string]any{
"protocolVersion": protocolVersion,
"agentProtocolVersion": protocolVersion,
"capabilities": []string{
"connect",
"test_connection",
"metadata",
"query",
"ddl",
},
}, false, nil
// … other methods …
}
}
The capabilities slice explicitly lists every JSON-RPC method the driver supports, such as connect, test_connection, metadata, query, and ddl.
Client-Side Usage
The DBX client initiates the handshake by sending a JSON-RPC request with method handshake and minimal parameters containing only the appVersion:
{
"jsonrpc": "2.0",
"id": 7,
"method": "handshake",
"params": { "appVersion": "dev" }
}
Upon receiving the response, the client parses the capabilities array and stores it in runtime state. Subsequent operations validate against this list before transmission, ensuring the client never attempts to invoke unsupported methods. A typical response from the Xugu driver appears as:
{
"protocolVersion": 1,
"agentProtocolVersion": 1,
"capabilities": [
"connect",
"test_connection",
"metadata",
"query",
"ddl"
]
}
Runtime Dynamic Detection Without Rebuilding
Because the handshake executes every time the agent launches, the set of available capabilities can change dynamically without rebuilding the DBX core. Adding new functionality—such as a bulk_load method—requires only modifying the capabilities slice in the driver's dispatch function and rebuilding that specific agent.
The client automatically adapts on the next connection because it relies entirely on the handshake response to determine the available API surface. This decoupling eliminates version synchronization issues between the core client and individual database drivers.
Implementation Examples by Driver
The handshake pattern is consistent across all drivers in the agents/drivers/ directory. Each driver hardcodes its capability list in the dispatch switch statement:
- Xugu Driver:
agents/drivers/xugu/main.go(lines 13-21) - Oracle Driver:
agents/drivers/oracle-go/main.go(lines 13-21)
Both files implement identical dispatch functions that return the protocolVersion, agentProtocolVersion, and capabilities array. This standardization ensures the core client can interact with any driver through the same JSON-RPC interface while respecting driver-specific limitations.
Summary
- DBX uses a JSON-RPC handshake immediately after agent startup to detect capabilities dynamically at runtime.
- Drivers declare supported operations in the
dispatchfunction within their respectivemain.gofiles. - The client stores the capability list from the handshake response and filters subsequent commands accordingly.
- New capabilities can be added by updating only the driver code; the core client adapts automatically on the next connection.
Frequently Asked Questions
What is the handshake method in DBX?
The handshake method is a JSON-RPC call initiated by the DBX client immediately after connecting to a database agent. It returns a JSON object containing protocolVersion and a capabilities array listing all supported operations like connect, query, and ddl. This method enables the client to discover what the driver can do without hardcoding driver-specific logic.
How does DBX handle unsupported capabilities?
The DBX client stores the capability list received during the handshake in its runtime state. Before sending any JSON-RPC request, the client checks whether the target method exists in the capability array. If a capability is not advertised, the client avoids sending that command, preventing runtime errors against drivers that lack specific functionality.
Can capabilities vary between different database drivers?
Yes, capabilities vary by driver and are declared independently in each driver's source code. For example, the Xugu driver in agents/drivers/xugu/main.go might advertise different capabilities than the Oracle driver in agents/drivers/oracle-go/main.go. The core client treats these declarations as the authoritative source of truth for what operations are available for that specific database connection.
Where is the handshake implemented in the source code?
The handshake implementation resides in each driver's dispatch function within their main.go files. Specifically, you will find the switch case for "handshake" returning the capability map in agents/drivers/xugu/main.go and agents/drivers/oracle-go/main.go. These functions return hardcoded capability lists that define the driver's API surface for that session.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →