Describe the bug
External plugin drivers cannot receive a full connection URI. Two independent gaps in src/utils/connectionStringParser.ts combine to make SRV-based drivers (MongoDB Atlas, and any future driver whose scheme carries semantics) unusable.
Gap 1 — the protocol is rejected
buildProtocolRegistry only registers two things per driver: normalizeProtocol(driver.id) and the protocol extracted from capabilities.connection_string_example. A plugin whose id is mongodb-atlas therefore only registers mongodb-atlas://. Pasting a real Atlas URI fails at connectionStringParser.ts:171:
Unsupported database driver: mongodb+srv. Supported: mongodb-atlas, mysql, postgres, postgresql, sqlite
PROTOCOL_ALIAS_GROUPS is a hardcoded list (postgres/postgresql, mysql/mariadb, sqlite/sqlite3), so a plugin cannot register an alias pair such as mongodb + mongodb+srv even by declaring an example — the example only registers one of the two.
Gap 2 — the URI is destroyed even when the protocol is accepted
Once parsing succeeds, parseConnectionString decomposes the URI into discrete fields (connectionStringParser.ts:200-228) and toConnectionParams forwards only those:
return {
driver: parsed.driver,
host: parsed.host,
port: parsed.port,
username: parsed.username,
password: parsed.password,
database: parsed.database,
};
The scheme and the entire query string are discarded. For mongodb+srv:// this is not recoverable:
mongodb+srv mandates a DNS SRV lookup to discover the replica-set members. A bare hostname with no port is not a valid substitute — the driver has no way to know it should resolve SRV records.
- Atlas URIs carry
retryWrites, w=majority, authSource, replicaSet and appName in the query string. All are dropped.
url.port is empty for SRV URIs, so port arrives as undefined and the plugin falls back to default_port (27017), which is wrong for a sharded Atlas cluster.
The observable result is that a connection can appear to be established while database enumeration returns nothing, because the reconstructed connection no longer points at the real cluster.
Grepping current main (39f5ab2) confirms there is no path that preserves the original string — there is no connection_uri / full_uri field anywhere in src-tauri/src or src/utils.
To Reproduce
- Install an external plugin driver that accepts a full URI. I used a MongoDB Atlas plugin whose
manifest.json declares "id": "mongodb-atlas", "default_port": 27017 and no connection_string_example.
- Open New Connection and paste a standard Atlas connection string:
mongodb+srv://user:pass@cluster0.xxxxx.mongodb.net/mydb?retryWrites=true&w=majority&appName=Cluster0
- The modal rejects it with
Unsupported database driver: mongodb+srv.
- Work around gap 1 by adding
"connection_string_example": "mongodb+srv://user:pass@host/db" to the plugin manifest so the protocol registers.
- Paste the same URI again. It now parses, but the plugin receives only
host=cluster0.xxxxx.mongodb.net, port=undefined, database=mydb — no SRV scheme, no query parameters.
- The connection does not resolve to the real cluster and databases fail to load.
OS Version
macOS 26.4 (25E246), arm64
Tabularis Version
v0.14.0 (also verified against main @ 39f5ab2)
Relevant Log Output
Unsupported database driver: mongodb+srv. Supported: mongodb-atlas, mysql, postgres, postgresql, sqlite
Suggested direction
The core need is that a plugin should be able to declare "I take the raw connection string, do not decompose it", and the host should carry that string through to the driver over JSON-RPC.
Roughly:
- A capability flag (e.g.
connection_string_passthrough) that makes parseConnectionString skip decomposition and preserve the original URI verbatim.
- A
connection_uri field on the connection model, forwarded to the external plugin on connect.
- Allow plugins to declare multiple protocols rather than deriving a single one from
driver.id plus one example, so alias pairs like mongodb / mongodb+srv work.
Because the URI embeds credentials, it should be treated as a secret: stored in the OS keychain rather than in connections.json, with the cached secret rolled back if persistence fails. A transient URI is acceptable for Test Connection, but a saved connection should require keychain availability.
I have a prototype of this against the v0.14.0 codebase. It predates the capability-driven protocol registry that main now has, so it needs to be reworked to fit the current architecture, and I have not yet verified end-to-end that databases enumerate correctly with it. I am happy to open a PR once it is rebased and properly verified — let me know if the direction above is one you would accept.
Describe the bug
External plugin drivers cannot receive a full connection URI. Two independent gaps in
src/utils/connectionStringParser.tscombine to make SRV-based drivers (MongoDB Atlas, and any future driver whose scheme carries semantics) unusable.Gap 1 — the protocol is rejected
buildProtocolRegistryonly registers two things per driver:normalizeProtocol(driver.id)and the protocol extracted fromcapabilities.connection_string_example. A plugin whose id ismongodb-atlastherefore only registersmongodb-atlas://. Pasting a real Atlas URI fails atconnectionStringParser.ts:171:PROTOCOL_ALIAS_GROUPSis a hardcoded list (postgres/postgresql,mysql/mariadb,sqlite/sqlite3), so a plugin cannot register an alias pair such asmongodb+mongodb+srveven by declaring an example — the example only registers one of the two.Gap 2 — the URI is destroyed even when the protocol is accepted
Once parsing succeeds,
parseConnectionStringdecomposes the URI into discrete fields (connectionStringParser.ts:200-228) andtoConnectionParamsforwards only those:The scheme and the entire query string are discarded. For
mongodb+srv://this is not recoverable:mongodb+srvmandates a DNS SRV lookup to discover the replica-set members. A barehostnamewith no port is not a valid substitute — the driver has no way to know it should resolve SRV records.retryWrites,w=majority,authSource,replicaSetandappNamein the query string. All are dropped.url.portis empty for SRV URIs, soportarrives asundefinedand the plugin falls back todefault_port(27017), which is wrong for a sharded Atlas cluster.The observable result is that a connection can appear to be established while database enumeration returns nothing, because the reconstructed connection no longer points at the real cluster.
Grepping current
main(39f5ab2) confirms there is no path that preserves the original string — there is noconnection_uri/full_urifield anywhere insrc-tauri/srcorsrc/utils.To Reproduce
manifest.jsondeclares"id": "mongodb-atlas","default_port": 27017and noconnection_string_example.Unsupported database driver: mongodb+srv."connection_string_example": "mongodb+srv://user:pass@host/db"to the plugin manifest so the protocol registers.host=cluster0.xxxxx.mongodb.net,port=undefined,database=mydb— no SRV scheme, no query parameters.OS Version
macOS 26.4 (25E246), arm64
Tabularis Version
v0.14.0 (also verified against
main@ 39f5ab2)Relevant Log Output
Suggested direction
The core need is that a plugin should be able to declare "I take the raw connection string, do not decompose it", and the host should carry that string through to the driver over JSON-RPC.
Roughly:
connection_string_passthrough) that makesparseConnectionStringskip decomposition and preserve the original URI verbatim.connection_urifield on the connection model, forwarded to the external plugin on connect.driver.idplus one example, so alias pairs likemongodb/mongodb+srvwork.Because the URI embeds credentials, it should be treated as a secret: stored in the OS keychain rather than in
connections.json, with the cached secret rolled back if persistence fails. A transient URI is acceptable for Test Connection, but a saved connection should require keychain availability.I have a prototype of this against the v0.14.0 codebase. It predates the capability-driven protocol registry that
mainnow has, so it needs to be reworked to fit the current architecture, and I have not yet verified end-to-end that databases enumerate correctly with it. I am happy to open a PR once it is rebased and properly verified — let me know if the direction above is one you would accept.