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.