Understanding the Chat2DB Plugin Architecture and SPI: A Complete Guide

Chat2DB uses a modular Plugin Architecture based on Java's Service Provider Interface (SPI) that allows developers to add support for new databases without modifying the core codebase.

The OtterMind/Chat2DB repository implements a contract‑first extensibility model where database‑specific logic is encapsulated in separate Maven modules. By leveraging Java's ServiceLoader mechanism and Spring dependency injection, the platform dynamically discovers and registers plugins at runtime, enabling plug‑and‑play support for diverse SQL and NoSQL systems.

Core Components of the Chat2DB Plugin Architecture

The SPI Module and Contract Interfaces

The SPI module (chat2db-community-server/chat2db-community-spi) defines the contracts that every database plugin must implement. These Java interfaces establish extension points for SQL syntax handling, metadata access, and execution services.

The two fundamental contracts are:

  • IPlugin – The base interface that every plugin must implement. It declares the database name, version, and references to dialect‑specific services.
  • ISqlSyntaxPlugin – Defines methods for SQL parsing, formatting, and auto‑completion specific to the target database grammar.

Additional granular interfaces like IDbWorkspaceDataSourceService, IDbSqlExecutionService, and IDbMetaDataService allow plugins to expose only the capabilities supported by their underlying database.

ServiceLoader Discovery Mechanism

Chat2DB relies on Java’s built‑in ServiceLoader class to discover implementations at runtime. Each plugin module ships a service provider configuration file located at:


src/main/resources/META-INF/services/ai.chat2db.spi.IPlugin

This file contains the fully‑qualified class name of the plugin implementation, enabling the JVM to locate and instantiate the plugin without explicit class loading code.

Plugin Module Structure

Database plugins reside as separate Maven modules under chat2db-community-plugins/. Each module follows a consistent structure:

  • Plugin Class – Implements IPlugin (e.g., TiDBPlugin, MongoDBPlugin, XUGUDBPlugin).
  • Syntax Plugin – Implements ISqlSyntaxPlugin for dialect‑specific SQL operations.
  • Supporting Classes – Parser, builder, metadata, and manager classes tailored to the specific database.

For example, the XuguDB plugin implementation lives at chat2db-community-server/chat2db-community-plugins/chat2db-community-xugudb/src/main/java/ai/chat2db/plugin/xugudb/XUGUDBPlugin.java, while the TiDB equivalent is located in the chat2db-community-tidb module.

How the Chat2DB SPI Works: Step-by-Step

The plugin lifecycle follows a strict registration pattern managed by the Spring context:

  1. Define Contracts – The SPI module declares interfaces in chat2db-community-spi/src/main/java/ai/chat2db/spi/ that specify expected behavior for SQL syntax, metadata extraction, and query execution.

  2. Implement the Plugin – Developers create a new Maven module under chat2db-community-plugins and implement IPlugin along with relevant service interfaces.

  3. Register via ServiceLoader – The plugin JAR includes a META-INF/services/ai.chat2db.spi.IPlugin file listing the implementation class, allowing automatic discovery.

  4. Spring Wiring – During application startup, Chat2DB scans the classpath for IPlugin services and registers each instance into a PluginRegistry (located in chat2db-community-start). The registry injects the appropriate beans into core domain services.

  5. Runtime Delegation – When a user selects a datasource, the system looks up the corresponding plugin by dialect name and delegates all database‑specific operations—such as SQL building, metadata extraction, and DDL generation—to that plugin’s implementations.

Implementing a Custom Database Plugin

Below is a complete skeleton demonstrating how to add support for a hypothetical MyAwesomeDB database.

First, create the main plugin class that implements IPlugin:

package ai.chat2db.plugin.myawesome;

import ai.chat2db.spi.IPlugin;
import org.springframework.stereotype.Component;

@Component
public class MyAwesomeDBPlugin implements IPlugin {
    @Override
    public String getName() {
        return "myawesome";
    }

    @Override
    public String getVersion() {
        return "1.0.0";
    }
    
    // Optional: expose syntax plugin class
    // @Override
    // public Class<? extends ISqlSyntaxPlugin> getSyntaxPluginClass() { ... }
}

Next, implement the SQL syntax contract for parsing and completion:

package ai.chat2db.plugin.myawesome;

import ai.chat2db.spi.ISqlSyntaxPlugin;
import org.springframework.stereotype.Component;

@Component
public class MyAwesomeSQLSyntaxPlugin implements ISqlSyntaxPlugin {
    // Implement parse, complete, format methods here
}

Create the ServiceLoader registration file at src/main/resources/META-INF/services/ai.chat2db.spi.IPlugin:

ai.chat2db.plugin.myawesome.MyAwesomeDBPlugin

Finally, register the module in the parent POM at chat2db-community-plugins/pom.xml:

<module>chat2db-community-myawesomedb</module>

When the application restarts, MyAwesomeDBPlugin will be discovered automatically and integrated into the core workflow.

Key Extension Points and Services

The SPI defines numerous granular interfaces that plugins can implement based on target database capabilities:

  • IDbMetaDataService – For schema introspection and table metadata retrieval.
  • IDbSqlExecutionService – For executing queries and managing result sets.
  • IDbWorkspaceDataSourceService – For connection pooling and workspace‑level datasource management.

Notable reference implementations include:

Summary

  • Chat2DB implements a Java SPI‑based plugin architecture that separates database‑specific logic from the core application.
  • The IPlugin and ISqlSyntaxPlugin interfaces in chat2db-community-spi define the mandatory contracts for all plugins.
  • ServiceLoader discovers plugins via META-INF/services/ai.chat2db.spi.IPlugin metadata files inside each plugin JAR.
  • Plugins reside as independent Maven modules under chat2db-community-plugins, with each module encapsulating one database dialect.
  • The PluginRegistry in chat2db-community-start handles Spring wiring and lifecycle management during application startup.

Frequently Asked Questions

What is the difference between Chat2DB's SPI and a traditional API?

The SPI (Service Provider Interface) is designed for extensibility by third‑party developers, whereas a traditional API is consumed by client code. In Chat2DB, the SPI defines contracts in the chat2db-community-spi module that plugin authors implement, while the core application acts as the consumer of those implementations. This inversion of control allows new databases to be added without modifying the core codebase.

How does Chat2DB discover plugins at runtime?

Chat2DB uses Java’s ServiceLoader mechanism. When the application starts, the PluginRegistry scans the classpath for JARs containing a file at META-INF/services/ai.chat2db.spi.IPlugin. This file lists the fully‑qualified class name of the plugin implementation, which Spring then instantiates and registers as a bean.

Can I extend Chat2DB to support a proprietary or internal database?

Yes. By creating a new Maven module under chat2db-community-plugins and implementing the IPlugin interface and relevant service contracts (such as ISqlSyntaxPlugin or IDbMetaDataService), you can integrate any JDBC‑compatible database. The modular design ensures your proprietary logic remains isolated while inheriting Chat2DB’s core UI and connection management features.

What files must be present in a Chat2DB plugin JAR for successful registration?

A valid plugin JAR must contain:

  1. An implementation class of ai.chat2db.spi.IPlugin (annotated with @Component).
  2. A service declaration file at META-INF/services/ai.chat2db.spi.IPlugin containing the implementation’s fully‑qualified class name.
  3. Spring‑managed components that implement the required SPI interfaces for your target database’s capabilities.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →