Skip to main content
Providers are how Bridge turns one CLI into a stable interface across different storage backends. Each provider is:
  • named in bridge.yaml
  • selected with --from <name>
  • responsible for connecting, listing, reading, and reporting health
Bridge ships with built-in providers for local files and SQL databases. This page covers their runtime behavior, guarantees, and current limitations.

How providers fit into Bridge

At runtime, Bridge:
  1. loads bridge.yaml
  2. resolves the provider by name
  3. connects using that provider’s URI
  4. calls list, read, or health
  5. returns structured JSON
That means the command shape stays stable even when the backend changes.
bridge ls --from files
bridge ls --from localdb
bridge ls --from db

bridge read README.md --from files
bridge read users/42 --from localdb
bridge read users/42 --from db

Connect-time verification

bridge connect now uses the same probe path that bridge status uses for backend health. By default, when you add or update a provider, Bridge:
  1. resolves any environment variables that are available in the current shell
  2. connects to the backend
  3. runs a health check
  4. only saves the provider if verification succeeds
Use --no-verify when you intentionally want to save a provider before the backend is reachable. Use --force when you intentionally want to replace an existing provider name. If a placeholder variable such as DATABASE_URL is not set in the current shell, Bridge saves the placeholder and marks the provider as unverified because it cannot probe the backend locally.

Capability model

The provider interface includes support for these capabilities:
  • read
  • list
  • write
  • delete
  • search
Current shipped providers are read-only:
ProviderReadListWriteDeleteSearch
Filesystemyesyesnonono
SQLiteyesyesnonono
Postgresyesyesnonono

Filesystem provider

Use the filesystem provider when you want Bridge to expose files and directories from a local project, docs folder, dataset, or generated output directory.

URI format

providers:
  files:
    type: filesystem
    uri: file://./docs
Bridge accepts:
  • relative paths like file://./docs
  • absolute paths like file:///Users/alice/project/docs
The target must exist and must be a directory when the provider connects.

What ls returns

bridge ls --from files lists the top-level contents of the configured root directory. Entries are returned as:
  • file
  • directory
Example:
[
  { "name": "README.md", "path": "README.md", "entry_type": "file" },
  { "name": "nested", "path": "nested", "entry_type": "directory" }
]
Current behavior worth knowing:
  • listing is not recursive
  • entries are sorted by name
  • file entries may include size and updated_at
  • directory entries do not include file size

What read returns

bridge read <path> --from files reads a file relative to the provider root. Examples:
bridge read README.md --from files
bridge read nested/deep.txt --from files
Bridge detects a content type from the file extension and then returns one of three data forms:
File kindReturned data.typeNotes
UTF-8 text filestextIncludes Markdown, plain text, YAML, TOML, CSV, HTML, and similar text formats
Valid JSON filesjsonParsed into JSON before returning
Non-text or non-UTF-8 filesbinaryReturned as base64-encoded content
Example text response:
{
  "data": {
    "type": "text",
    "content": "# Hello\n\nWorld\n"
  },
  "metadata": {
    "source": "filesystem",
    "path": "hello.md",
    "content_type": "text/markdown"
  }
}
Example binary response:
{
  "data": {
    "type": "binary",
    "content": "AAH//g==",
    "encoding": "base64"
  },
  "metadata": {
    "source": "filesystem",
    "path": "binary.bin",
    "content_type": "application/octet-stream"
  }
}

Security behavior

The filesystem provider enforces a root boundary. Once connected to a directory, Bridge:
  • canonicalizes the provider root
  • canonicalizes requested paths
  • rejects reads that escape the root directory
So a path like ../../etc/passwd is blocked instead of being resolved outside the configured provider.

Common filesystem errors

If the configured file:// URI points to a directory that does not exist, bridge connect fails verification by default. Pass --no-verify only if you want to save the provider before that directory exists.
A filesystem provider must point to a directory, not to a single file.
If you try to read a file that does not exist under the configured root, Bridge returns a provider error.
If a requested path escapes the configured root, Bridge returns a path traversal error.

SQLite provider

Use the SQLite provider when you want Bridge to expose tables and rows from a local SQLite database file without running a separate database server.

URI format

providers:
  localdb:
    type: sqlite
    uri: sqlite://./local.db
Bridge accepts:
  • relative file paths like sqlite://./local.db
  • absolute file paths like sqlite:///Users/alice/project/local.db
  • in-memory databases like sqlite://:memory:
  • SQLite modes such as sqlite://./local.db?mode=ro and sqlite://./local.db?mode=rwc
By default, bridge connect verifies the SQLite database before it saves the config. That means the file must already exist unless you use a mode that allows creation or memory-backed access such as ?mode=rwc or sqlite://:memory:. If you want to save first and verify later, pass --no-verify.

What ls returns

bridge ls --from localdb returns user tables from the database. Example:
[
  { "name": "users", "path": "users", "entry_type": "table" },
  { "name": "orders", "path": "orders", "entry_type": "table" }
]
Current behavior worth knowing:
  • internal tables whose names start with sqlite_ are filtered out
  • entries are returned as table
  • table metadata does not currently include size or timestamps

What read returns

The SQLite provider supports the same two path shapes as Postgres.

Read a whole table

bridge read users --from localdb
This returns a JSON array of rows ordered by the table’s single-column primary key.

Read a single row by primary key

bridge read users/42 --from localdb
This returns a single JSON object.

Important SQLite limitations today

The current implementation is intentionally conservative.
  • table names must match [a-zA-Z_][a-zA-Z0-9_]*
  • whole-table reads require a single-column primary key
  • row reads also require a single-column primary key
  • tables without a primary key are listed by ls but cannot be read with bridge read
  • tables with composite primary keys are listed by ls but cannot be read with bridge read
  • whole-table reads honor read --limit, and fall back to 100 rows when no explicit limit is provided
  • single-row reads ignore --limit
If you do not pass --limit, Bridge falls back to 100 rows for whole-table SQLite reads.

Type handling

SQLite rows are returned as JSON. Bridge maps common SQLite affinities into JSON values:
  • integers to JSON numbers
  • real and numeric values to JSON numbers when possible
  • booleans to JSON booleans
  • text-like values to JSON strings
  • BLOB values to base64-encoded strings
  • SQL NULL to JSON null
Declared types such as DECIMAL, JSON, and VARCHAR still follow SQLite’s affinity rules, so some values come back as strings rather than nested JSON.

Metadata behavior

For SQLite reads, the metadata source is the configured SQLite URI. Bridge stores the table path you read in metadata.path and reports application/json as the content type.

Security behavior

The SQLite provider keeps its query surface intentionally small:
  • it only lists tables
  • it validates table identifiers before they reach SQL
  • it quotes identifiers when queries are built
  • it binds primary-key values as query parameters for single-row reads

Common SQLite errors

If the configured SQLite file does not exist, bridge connect fails verification unless you use an existing file, sqlite://:memory:, a creation mode such as ?mode=rwc, or --no-verify.
If the requested table does not exist in the database, Bridge returns a provider error and suggests using bridge ls --from <provider> to see available tables.
If the table exists but the requested primary key value does not, Bridge returns a provider error for that row path.
If a table has no primary key, Bridge currently refuses both whole-table and single-row reads for that table.
If a table uses a composite primary key, Bridge currently refuses the read rather than guessing how the row path should be encoded.
Bridge rejects suspicious table names before they reach SQL. This blocks obvious injection attempts and keeps table paths constrained to simple identifiers.

Postgres provider

Use the Postgres provider when you want agents to list tables and read rows from a PostgreSQL database through the same Bridge command surface.

URI format

providers:
  db:
    type: postgres
    uri: ${DATABASE_URL}
Bridge accepts:
  • postgres://...
  • postgresql://...
In practice, most teams should use an environment variable for credentials. Bridge can generate that config for you:
bridge connect DATABASE_URL --type postgres --as db
By default, bridge connect verifies that the database is reachable before it saves the provider. If you want to keep the config before the database is reachable, pass --no-verify. If the environment variable is not set in your current shell, Bridge saves the placeholder and marks it as unverified.

What ls returns

bridge ls --from db returns tables from the public schema. Example:
[
  { "name": "users", "path": "users", "entry_type": "table" },
  { "name": "orders", "path": "orders", "entry_type": "table" }
]
Current behavior worth knowing:
  • only the public schema is listed
  • entries are returned as table
  • table metadata does not currently include size or timestamps

What read returns

The Postgres provider supports two path shapes.

Read a whole table

bridge read users --from db
This returns a JSON array of rows.

Read a single row by primary key

bridge read users/42 --from db
This returns a single JSON object. Bridge detects the table’s primary key, casts the row identifier to the correct column type, and fetches that single row.

Important Postgres limitations today

The current implementation is intentionally conservative.
  • Reads only work against tables in the public schema
  • Table names must match [a-zA-Z_][a-zA-Z0-9_]*
  • Whole-table reads require a single-column primary key
  • Row reads also require a single-column primary key
  • Tables without a primary key are listed by ls but cannot be read with bridge read
  • Tables with composite primary keys are listed by ls but cannot be read with bridge read
  • Whole-table reads honor read --limit, and fall back to 100 rows when no explicit limit is provided
If you do not pass --limit, Bridge falls back to 100 rows for whole-table Postgres reads.

Type handling

Postgres rows are returned as JSON. Bridge currently handles common types such as:
  • integers
  • floats and numeric values
  • booleans
  • json and jsonb
For other column types, Bridge falls back to a string conversion where possible. If a value cannot be read in the expected way, it may be returned as null.

Metadata behavior

For Postgres reads, the metadata source is not just "postgres". Bridge stores a redacted version of the connection URI so the response can identify the backend without leaking passwords.

Security behavior

The Postgres provider is designed to keep table and row reads safe:
  • identifiers are validated before being used in SQL
  • identifiers are quoted when queries are built
  • row values are passed as bound parameters
  • connection URIs are redacted in user-facing metadata and status messages

Common Postgres errors

If the requested table does not exist in the public schema, Bridge returns a provider error and suggests using bridge ls --from <provider> to see available tables.
If the table exists but the requested primary key value does not, Bridge returns a provider error for that row path.
If a table has no primary key, Bridge cannot safely support bridge read <table> or bridge read <table>/<id> for that table in the current implementation.
If a table uses a composite primary key, Bridge currently refuses the read rather than guessing how the row path should be encoded.
Bridge rejects suspicious table names before they reach SQL. This blocks obvious injection attempts and keeps table paths constrained to simple identifiers.

Health checks

All providers support bridge status.
  • The filesystem provider reports whether the configured directory exists
  • The SQLite provider runs a lightweight SELECT 1 health query and reports the configured SQLite URI
  • The Postgres provider runs a lightweight SELECT 1 health query and includes latency
Example:
{
  "providers": {
    "files": {
      "connected": true,
      "latency_ms": 0,
      "message": "Directory: /path/to/docs"
    },
    "localdb": {
      "connected": true,
      "latency_ms": 1,
      "message": "Connected to sqlite:///path/to/local.db"
    },
    "db": {
      "connected": true,
      "latency_ms": 12,
      "message": "Connected to postgres://user:***@localhost:5432/mydb"
    }
  }
}

Planned providers

Bridge’s long-term direction is broader than the providers available today. The current CLI roadmap calls out:
  • S3
  • vector store providers such as Qdrant and Pinecone
The goal is to keep the agent-facing model the same even as the set of supported backends grows.

Next steps

Configuration

See how provider definitions live inside bridge.yaml.

CLI interface

See how provider reads and lists become structured JSON output.