RLM data sources
The RLM engine runs in your boundary, so a data source is something the engine process can reach directly: a file on disk, a database it holds a credential for, or a trusted broker on your network. Credentials never leave that process, and ModelRelay never sees the rows.
Availability
| Source | Flag | Notes |
|---|---|---|
| SQLite file | --db |
Opened read-only |
| PostgreSQL | --postgres-dsn-env |
DSN stays in the local mrl process |
| Snowflake | --snowflake-broker-url |
Credentials and authoritative SQL policy stay in a separate broker container |
| Remote MCP | --mcp-config |
Trusted host owns the endpoint, secrets, and sessions |
| Local files and stdin | -a / piped stdin |
Attached paths can be opened by generated code |
| Inline JSON | built from attachments | Available as context |
Local SQLite
Use --db to expose a SQLite database as a read-only data source:
mrl rlm \
"Compare monthly revenue by plan and explain the largest changes" \
--db ./billing.db
The default sandbox name is db. Change it when the name carries useful meaning:
mrl rlm "Find suspicious refunds" \
--db ./commerce.db \
--db-name commerce
--sql-profile applies a configured SQL policy. Without one, the CLI uses its default permissive read-only policy. This policy is a guardrail, not a confidentiality boundary: generated Python runs on the same machine and can open files the current user can read. Point RLM only at a database the caller may fully inspect, and use a restricted copy or view when sensitive tables must be excluded.
SQL policy validation
Before executing a SQLite or PostgreSQL query, mrl sends the SQL string and selected policy or profile reference to POST /api/v1/sql/validate. Database credentials and rows stay in the local process. The local broker executes only the normalized SQL returned by the validator and still applies its own read-only and resource limits.
Local PostgreSQL
Put a least-privilege PostgreSQL DSN in an environment variable and pass the variable name:
export MODELRELAY_POSTGRES_DSN='postgres://rlm_reader:password@db.internal/analytics?sslmode=require'
mrl rlm "Find the largest changes in account health" \
--postgres-dsn-env MODELRELAY_POSTGRES_DSN \
--db-name warehouse
The trusted local broker owns the credential and driver, validates each query, and executes it in a read-only transaction with hard timeout, row, and response-size limits. Queries that exceed a local limit fail closed. Generated Python never receives the DSN or raw connection. See the PostgreSQL edge connector guide.
Snowflake edge broker
For Snowflake, run the trusted broker and RLM runner as separate processes or containers. The broker alone receives the Snowflake configuration and workload-identity, OAuth, or key-pair credential. It validates every query locally against its authoritative Snowflake SQL policy, then applies independent row, byte, execution-time, and queued-time caps.
mrl snowflake serve \
--config /run/modelrelay/snowflake.json \
--listen 0.0.0.0:8081 \
--broker-token-env MODELRELAY_SNOWFLAKE_BROKER_TOKEN
mrl rlm "Compare weekly revenue and explain anomalies" \
--snowflake-broker-url http://broker:8081/v1/sql \
--snowflake-broker-token-env MODELRELAY_SNOWFLAKE_BROKER_TOKEN
The runner receives only the broker URL and a short-lived capability token. It must not receive the Snowflake config or credential mounts. See the Snowflake edge connector guide for the image, configuration, Snowflake grants, and health contract.
Remote MCP
mrl rlm --mcp-config <file> mounts a Droste remote MCP provider in the trusted local host. The file carries endpoint/tool policy and logical secret references; mrl resolves their values from named environment variables through a tenant/source-scoped loopback broker. Generated Python receives only connector-neutral capability bindings. Run mrl inside the network allowed to reach the MCP server. See Remote MCP providers for the exact configuration.
Local files
Attach one or more local files:
mrl rlm "Summarize the recurring incident patterns" \
-a ./incidents/*.md \
-a ./service-map.json
Piped stdin is automatically attached when no explicit attachment is supplied:
git log --stat --since="3 months ago" | \
mrl rlm "Which areas changed most, and what risks follow?"
Attachments are represented in context["files"]. Small text files include an inline text field; larger inputs can be loaded from their local path by the runtime. --inline-text-max-bytes controls the inline cutoff.
Mounting more than one source
--db, --postgres-dsn-env, and --snowflake-broker-url are mutually exclusive: one run has at most one SQL source, named by --db-name. --mcp-config is repeatable and mounts alongside it.
Every source gets a name in the sandbox. A SQL source supplies the default. Without one, mounting more than a single MCP provider requires naming the default explicitly:
mrl rlm "Reconcile the policy with open customer requests" \
--mcp-config ./docs-mcp.json \
--mcp-config ./tickets-mcp.json \
--default-source docs
Choosing a source
- Start with local SQLite for a prototype, PostgreSQL for a customer-controlled transactional database, or the Snowflake edge broker for approved warehouse data.
- Use attachments for local files, exports, logs, and document collections.
- Use remote MCP when the data already sits behind an approved read-only MCP server.
- Run the engine inside your VPC when credentials and data access must stay on a private network.