Skip to main content
Bridge is a CLI-first product, so the command surface is the product surface. This page documents the commands Bridge exposes today, what they do, and how they behave at runtime.

Command map

Bridge currently exposes these subcommands:
CommandPurpose
initCreate a bridge.yaml file in the current directory
connectAdd and verify a named provider in bridge.yaml
removeRemove a named provider from bridge.yaml
statusCheck the health of configured providers
lsList entries from a provider
readRead structured context from a provider
generate mcpGenerate a bridge.mcp/v1 manifest from an OpenAPI spec, Postgres, or SQLite
mcp serveServe a manifest as an MCP server over stdio
mcp serve-httpServe a manifest as an MCP server over HTTP
updateCheck for and install CLI updates
completionsGenerate shell completion scripts

Command conventions

Most Bridge commands follow the same runtime pattern:
  1. load bridge.yaml from the current directory
  2. resolve a named provider if the command needs one
  3. perform a provider operation inside the configured timeout
  4. print structured JSON on success
That means the CLI is predictable for both humans and agents:
  • successful commands print JSON to stdout
  • failures print JSON to stderr
  • failures exit with a non-zero status code
Example error output:
{
  "error": {
    "code": "config_not_found",
    "message": "bridge.yaml not found. Run `bridge init` to create one."
  }
}
Bridge currently uses:
  • exit code 1 for most validation and provider errors
  • exit code 2 for I/O, database, and timeout failures

Global options

All commands support the global --timeout flag:
bridge --timeout 60 status
bridge --timeout 10 read README.md --from files
FlagDefaultMeaning
--timeout <seconds>30Timeout for provider operations
Bridge also supports the standard top-level help and version flags:
  • bridge --help
  • bridge --version

Typical workflow

Most teams use the commands in this order:
bridge init
bridge connect file://./docs --as files
bridge status
bridge ls --from files
bridge read README.md --from files
These examples assume the target directory or database already exists. bridge connect verifies targets by default. If you are connecting a database, the flow stays the same:
bridge connect postgres://localhost:5432/mydb --as db
bridge status
bridge ls --from db
bridge read users --from db --limit 25
SQLite follows the same command shape:
bridge connect sqlite://./local.db?mode=rwc --as localdb
bridge status
bridge ls --from localdb
bridge read users --from localdb --limit 25
For a safer setup that keeps the real connection string out of bridge.yaml, connect with an environment variable name instead:
export DATABASE_URL=postgres://user:pass@localhost:5432/mydb
bridge connect DATABASE_URL --type postgres --as db
bridge status

bridge init

Create a new bridge.yaml in the current directory.

Usage

bridge init

What it does

  • creates bridge.yaml if it does not already exist
  • uses the current directory name as the default project name
  • initializes providers as an empty map

Success output

On first run:
{
  "status": "created",
  "path": "bridge.yaml",
  "name": "my-project"
}
If the file already exists, Bridge does not overwrite it:
{
  "status": "already_exists",
  "path": "bridge.yaml"
}

Typical use

mkdir my-agent-project
cd my-agent-project
bridge init

bridge connect

Add a named provider connection to bridge.yaml.

Usage

bridge connect <target> --as <NAME> [--type <provider>] [--force] [--no-verify]
<target> can be:
  • a literal URI such as file://./docs, sqlite://./local.db, or postgres://localhost:5432/mydb
  • a bare environment variable name such as DATABASE_URL

Examples

bridge connect file://./docs --as files
bridge connect sqlite://./local.db?mode=rwc --as localdb
bridge connect postgres://localhost:5432/mydb --as db
bridge connect DATABASE_URL --type postgres --as db
bridge connect SQLITE_DATABASE_URL --type sqlite --as localdb
bridge connect DATABASE_URL --type postgres --as db --force
bridge connect postgres://localhost:5432/mydb --as db --no-verify

Flags

  • --type <provider> is required when <target> is an environment variable name
  • --force replaces an existing provider with the same name
  • --no-verify saves the provider without checking connectivity first

What it does

  • loads the current bridge.yaml
  • interprets <target> as either a literal URI or an environment variable name
  • infers the provider type from a literal URI scheme when possible
  • refuses to overwrite an existing provider name unless you pass --force
  • verifies the provider connection and health by default
  • saves the updated config back to disk after successful verification
If you pass --no-verify, Bridge saves the provider immediately and returns saved_unverified instead of connected. When <target> is an environment variable name, bridge connect writes it into bridge.yaml as ${TARGET} and requires --type <provider>. If that variable is not set in your current shell, Bridge still saves the placeholder but marks the connection as unverified because it cannot probe the backend locally. If verification fails, Bridge leaves bridge.yaml unchanged and returns connection_verification_failed.

Success output

Verified connection:
{
  "latency_ms": 3,
  "name": "db",
  "status": "connected",
  "type": "postgres",
  "uri": "${DATABASE_URL}",
  "verified": true
}
Saved without verification:
{
  "message": "Verification skipped (--no-verify).",
  "name": "db",
  "status": "saved_unverified",
  "type": "postgres",
  "uri": "postgres://localhost:5432/mydb",
  "verified": false
}

Supported URI schemes

Current built-in inference supports:
  • file://...filesystem
  • sqlite://...sqlite
  • postgres://...postgres
  • postgresql://...postgres
Unsupported or malformed URIs fail with invalid_uri.

Environment-variable targets

When you pass a bare environment variable name such as DATABASE_URL, Bridge:
  • requires --type
  • stores uri: ${DATABASE_URL} in bridge.yaml
  • resolves the actual value from the current process environment when it can verify the provider immediately
  • resolves the value later from the process environment when you run status, ls, or read
If the variable is missing when you run bridge connect, Bridge saves the placeholder and returns saved_unverified rather than failing the write. Bridge does not automatically load a .env file.

Common failure cases

  • bridge.yaml is missing
  • <target> is neither a supported URI nor a valid environment variable name
  • --type is missing for an environment-variable target
  • a provider with the same name already exists and you did not pass --force
  • the backend cannot be reached or fails its health check during verification
  • an environment variable referenced by bridge.yaml is not set later at runtime

bridge remove

Remove a named provider connection from bridge.yaml.

Usage

bridge remove <NAME>

Example

bridge remove files

Success output

{
  "status": "removed",
  "name": "files"
}

Failure behavior

If the provider name does not exist, Bridge returns a provider_not_found error and includes the currently available provider names.

bridge status

Check the health of all configured providers.

Usage

bridge status

What it does

For each provider in bridge.yaml, Bridge:
  1. expands environment variables in the URI
  2. creates the provider
  3. connects to it
  4. runs that provider’s health check

Success output

{
  "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"
    }
  }
}

Notes

  • the filesystem provider reports a directory status
  • the SQLite provider runs a lightweight health query
  • the Postgres provider runs a lightweight health query
  • URIs are redacted in status messages so passwords are not exposed
  • provider status is reported per entry, so one broken provider does not stop Bridge from checking the others

bridge ls

List entries from a provider.

Usage

bridge ls --from <NAME>

Examples

bridge ls --from files
bridge ls --from db

Success output

Filesystem example:
[
  { "name": "README.md", "path": "README.md", "entry_type": "file" },
  { "name": "nested", "path": "nested", "entry_type": "directory" }
]
Postgres example:
[
  { "name": "users", "path": "users", "entry_type": "table" },
  { "name": "orders", "path": "orders", "entry_type": "table" }
]
SQLite uses the same table entry shape for ls.

Important runtime note

The current --help text says --from is optional, but the current implementation still requires it. If you omit --from, Bridge returns a provider error asking you to specify a provider name.

Typical use

Use ls to discover valid paths before you call read.

Common failure cases

  • config_not_found if there is no bridge.yaml in the current directory
  • provider_not_found if --from names a provider that is not configured
  • provider_error if the backend cannot connect or the configured root is invalid
  • timeout if the provider does not respond before the configured timeout

bridge read

Read structured context from a provider.

Usage

bridge read <PATH> --from <NAME> [--limit <N>]

Examples

Filesystem:
bridge read README.md --from files
bridge read nested/deep.txt --from files
Postgres:
bridge read users --from db
bridge read users/42 --from db
bridge read users --from db --limit 25
SQLite:
bridge read users --from localdb
bridge read users/42 --from localdb
bridge read users --from localdb --limit 25

Output

read always returns a structured ContextValue object with:
  • data
  • metadata
Example:
{
  "data": {
    "type": "text",
    "content": "# Hello\n\nFile contents here."
  },
  "metadata": {
    "source": "filesystem",
    "path": "README.md",
    "content_type": "text/markdown"
  }
}

Current path shapes

The meaning of <PATH> depends on the provider:
ProviderPath shapeExample
filesystemrelative file path under the provider rootREADME.md
postgrestable nameusers
postgrestable plus primary keyusers/42
sqlitetable nameusers
sqlitetable plus primary keyusers/42

--limit

--limit is relevant for database-backed reads that return multiple rows.
  • default: 100
  • applies to whole-table Postgres and SQLite reads
  • is ignored for single-row Postgres and SQLite reads
  • if omitted, Bridge falls back to 100

Path semantics depend on the provider

  • Filesystem paths are file paths under the provider root
  • Postgres and SQLite paths are either table or table/primary_key
For the provider-specific behavior of read, see Providers.

Common failure cases

  • provider_not_found if the provider name passed to --from is not configured
  • path_traversal if a filesystem read escapes the provider root
  • provider_error if the file, table, or row does not exist
  • timeout if the provider does not finish the read before the timeout

bridge generate mcp

Generate a bridge.mcp/v1 manifest from an OpenAPI spec, a Postgres connection, or a SQLite connection.

Usage

bridge generate mcp --from openapi <SPEC> --name <NAME> --out <FILE> [options]
bridge generate mcp --from db --connection <NAME> --name <NAME> --out <FILE> [options]

Flags

FlagRequiredDescription
--from openapi <path>one of --fromPath to an OpenAPI 3.0 spec file (JSON or YAML)
--from dbone of --fromIntrospect a Postgres or SQLite connection from bridge.yaml
--connection <name>with --from dbName of a Bridge provider in bridge.yaml
--schema <schema>noDatabase schema to introspect. Defaults to public
--name <name>yesName for the generated MCP server
--out <file>yesOutput path for the manifest file
--base-url-env <VAR>OpenAPI onlyEnvironment variable holding the API base URL
--bearer-env <VAR>noEnvironment variable holding the bearer token
--forcenoOverwrite an existing file at --out

What it does

From OpenAPI: Bridge parses the spec, extracts GET operations, maps each operation to an MCP tool with an input schema, and writes the manifest. Operations that cannot be mapped are reported in the skipped field of the output. At least one base URL must be available — either from the spec’s servers array or via --base-url-env. From database: Bridge connects to the named Postgres or SQLite provider, introspects the schema, and generates list_* and get_*_by_* tools for each table. The manifest stores the connection name, not the connection string, so it is safe to commit.

Success output

{
  "status": "generated",
  "manifest": "my-api.mcp.yaml",
  "name": "my-api",
  "tools": ["list_users", "get_user_by_id"],
  "skipped": [],
  "client_snippet": {
    "mcpServers": {
      "my-api": {
        "command": "/usr/local/bin/bridge",
        "args": ["mcp", "serve", "/absolute/path/to/my-api.mcp.yaml"]
      }
    }
  }
}
The client_snippet is the exact config block to paste into Claude Desktop, Cursor, or any MCP client that uses the mcpServers format.

Examples

# From an OpenAPI spec with auth
bridge generate mcp \
  --from openapi ./openapi.yaml \
  --name petstore \
  --base-url-env PETSTORE_URL \
  --bearer-env PETSTORE_TOKEN \
  --out petstore.mcp.yaml

# From a Postgres or SQLite connection
bridge generate mcp \
  --from db \
  --connection db \
  --name myapp-db \
  --out myapp-db.mcp.yaml

# From a non-default schema, overwriting an existing manifest
bridge generate mcp \
  --from db \
  --connection db \
  --schema analytics \
  --name analytics \
  --out analytics.mcp.yaml \
  --force

Limitations

  • Only GET operations are supported from OpenAPI specs
  • Only Postgres and SQLite are supported as database sources
  • bridge.yaml must exist and the named connection must be reachable when using --from db
For the full manifest format, see MCP manifest.

bridge mcp serve

Serve a bridge.mcp/v1 manifest as a live MCP server over stdio (JSON-RPC 2.0).

Usage

bridge mcp serve <MANIFEST>

What it does

  • reads and validates the manifest at the given path
  • resolves any environment variables referenced in the manifest
  • starts a JSON-RPC 2.0 MCP server on stdin/stdout
  • handles tools/list and tools/call requests from MCP clients
  • for OpenAPI-backed tools: forwards calls as HTTP requests to the backend API
  • for database-backed tools: executes parameterized SQL SELECTs against the configured database provider
The process runs until the MCP client closes the connection. This is the mode used by Claude Desktop, Cursor, and other MCP hosts that launch MCP servers as subprocesses.

Example

bridge mcp serve ./petstore.mcp.yaml

Configuration

Bridge looks for bridge.yaml in the manifest’s directory when resolving database connections. Place your manifest next to or below the bridge.yaml file that defines the relevant providers. Environment variables referenced in the manifest (base_url_env, bearer_env, provider URIs with ${VAR}) must be set before running the server.

Wiring into Claude Desktop

Paste the client_snippet from bridge generate mcp into your Claude Desktop config at ~/Library/Application Support/Claude/claude_desktop_config.json:
{
  "mcpServers": {
    "petstore": {
      "command": "/usr/local/bin/bridge",
      "args": ["mcp", "serve", "/absolute/path/to/petstore.mcp.yaml"]
    }
  }
}
Restart Claude Desktop to pick up the change.

bridge mcp serve-http

Serve a bridge.mcp/v1 manifest as an MCP server over HTTP using the Streamable HTTP transport.

Usage

bridge mcp serve-http <MANIFEST> [options]

Flags

FlagDefaultEnv varDescription
--bind <HOST:PORT>127.0.0.1:8080BRIDGE_MCP_BINDAddress to listen on
--public-url <URL>BRIDGE_MCP_PUBLIC_URLPublic base URL reported in health output and logs
--max-header-bytes <N>32768 (32 KB)BRIDGE_MCP_MAX_HEADER_BYTESMax HTTP header bytes per request
--max-body-bytes <N>1048576 (1 MB)BRIDGE_MCP_MAX_BODY_BYTESMax HTTP body bytes per request
--read-timeout-secs <N>15BRIDGE_MCP_READ_TIMEOUT_SECSBudget for reading an HTTP request off the wire
--request-timeout-secs <N>global --timeoutBRIDGE_MCP_REQUEST_TIMEOUT_SECSBudget for handling a request after it is read
--shutdown-grace-secs <N>10BRIDGE_MCP_SHUTDOWN_GRACE_SECSTime to drain in-flight requests on shutdown
--allow-origin <ORIGIN>Extra Origins to accept (repeat for multiple)
All flags can also be set via the corresponding environment variable.

Endpoints

PathMethodPurpose
/mcpPOSTMCP endpoint (Streamable HTTP transport)
/healthzGETLiveness check. Returns 200 when the server is running.
/readyzGETReadiness check. Returns 200 when the server can handle requests.

CORS and origin policy

Requests with no Origin header are always accepted (non-browser clients do not send one). Browser-originated requests must have an Origin that is either a loopback address or one of the values passed to --allow-origin.

Examples

# Default: bind to localhost:8080
bridge mcp serve-http ./petstore.mcp.yaml

# Bind on all interfaces, port 9000
bridge mcp serve-http ./petstore.mcp.yaml --bind 0.0.0.0:9000

# With public URL and a browser-friendly origin
bridge mcp serve-http ./petstore.mcp.yaml \
  --bind 0.0.0.0:9000 \
  --public-url https://mcp.example.com \
  --allow-origin https://app.example.com

Graceful shutdown

The server listens for SIGTERM and SIGINT. On receipt, it stops accepting new connections and waits up to --shutdown-grace-secs for in-flight requests to complete before exiting.

bridge update

Check for and install CLI updates.

Usage

bridge update [--check]

Flags

FlagDescription
--checkReport whether an update is available without installing it

What it does

Without --check, Bridge checks for a newer release and installs it if one is available. With --check, Bridge reports the current version and the latest available version without making any changes.

Example

# Install the latest version
bridge update

# Just check — don't install
bridge update --check

bridge completions

Generate shell completion scripts for supported shells.

Usage

bridge completions <SHELL>
Supported shells today:
  • bash
  • elvish
  • fish
  • powershell
  • zsh

Examples

bridge completions zsh
bridge completions fish
bridge completions powershell

What it outputs

bridge completions writes the completion script text to stdout. You can then save or source that output using your shell’s normal setup flow. Unlike provider commands, completions does not need bridge.yaml and does not talk to any backend. See Installation for the current installer behavior, completion file locations, and manual setup examples for each shell.

Common error codes

The most useful error codes to know when scripting Bridge are:
  • config_not_found
  • invalid_uri
  • env_var_not_set
  • provider_not_found
  • provider_error
  • timeout
  • path_traversal
  • invalid_identifier
See Security and errors for the full failure model, timeout behavior, and current safety guardrails.

Choosing the right command

  • Use init once per project
  • Use connect when adding or updating a backend
  • Use remove when cleaning up provider aliases
  • Use status when debugging connectivity
  • Use ls when discovering valid paths
  • Use read when you want the actual context payload
  • Use generate mcp when you want to expose a backend as an MCP server
  • Use mcp serve to run an MCP server locally for Claude Desktop or Cursor
  • Use mcp serve-http to run an MCP server over HTTP for remote clients
  • Use update to keep the CLI current
  • Use completions when improving your shell workflow

Installation

See install methods, PATH behavior, and how the official installers set up completions.

Configuration

Learn how bridge.yaml is structured and how commands resolve provider names.

Providers

See what filesystem, sqlite, and postgres actually return for ls, read, and status.

MCP manifest

See the full bridge.mcp/v1 format and what each field controls.

Generate an MCP server

End-to-end guide for generating a manifest from an OpenAPI spec, Postgres, or SQLite.

Serve an MCP server

Run a manifest over stdio or HTTP and wire it into Claude Desktop or Cursor.

Security and errors

Understand timeout handling, error codes, secret redaction, and Bridge’s current guardrails.

CLI interface

See the higher-level JSON contract that sits behind these commands.